diff --git a/engine/src/flutter/impeller/golden_tests/BUILD.gn b/engine/src/flutter/impeller/golden_tests/BUILD.gn index c58591baac..a3156120b2 100644 --- a/engine/src/flutter/impeller/golden_tests/BUILD.gn +++ b/engine/src/flutter/impeller/golden_tests/BUILD.gn @@ -93,6 +93,7 @@ if (is_mac) { "//flutter/impeller/display_list:aiks_unittests_golden", "//flutter/impeller/display_list:display_list_unittests_golden", "//flutter/impeller/fixtures", + "//flutter/impeller/renderer:renderer_unittests_golden", "//flutter/third_party/angle:libEGL", "//flutter/third_party/angle:libGLESv2", "//flutter/third_party/googletest:gtest", diff --git a/engine/src/flutter/impeller/renderer/BUILD.gn b/engine/src/flutter/impeller/renderer/BUILD.gn index fe75154f28..fdc2ae7d98 100644 --- a/engine/src/flutter/impeller/renderer/BUILD.gn +++ b/engine/src/flutter/impeller/renderer/BUILD.gn @@ -96,10 +96,9 @@ impeller_component("renderer") { deps = [ "//flutter/fml" ] } -impeller_component("renderer_unittests") { - testonly = true - - sources = [ +template("renderer_unittests_component") { + target_name = invoker.target_name + predefined_sources = [ "blit_pass_unittests.cc", "capabilities_unittests.cc", "device_buffer_unittests.cc", @@ -107,20 +106,45 @@ impeller_component("renderer_unittests") { "pool_unittests.cc", "renderer_unittests.cc", ] - - deps = [ - ":renderer", - "../fixtures", - "../playground:playground_test", - "../tessellator:tessellator_libtess", - "//flutter/testing:testing_lib", - ] - - if (impeller_enable_compute) { - sources += [ "compute_unittests.cc" ] + impeller_component(target_name) { + testonly = true + if (defined(invoker.defines)) { + defines = invoker.defines + } else { + defines = [] + } + sources = predefined_sources + if (defined(invoker.deps)) { + deps = invoker.deps + } else { + deps = [] + } + deps += [ + ":renderer", + "../fixtures", + "../playground:playground_test", + "../tessellator:tessellator_libtess", + "//flutter/impeller/display_list:display_list", + "//flutter/testing:testing_lib", + ] + if (defined(invoker.public_configs)) { + public_configs = invoker.public_configs + } } } +renderer_unittests_component("renderer_unittests") { + deps = [ "//flutter/impeller/display_list:aiks_unittests" ] +} + +renderer_unittests_component("renderer_unittests_golden") { + deps = [ "//flutter/impeller/display_list:aiks_unittests_golden" ] + defines = [ + "IMPELLER_GOLDEN_TESTS", + "IMPELLER_ENABLE_VALIDATION=1", + ] +} + impeller_component("renderer_dart_unittests") { testonly = true diff --git a/engine/src/flutter/impeller/renderer/backend/gles/blit_command_gles.cc b/engine/src/flutter/impeller/renderer/backend/gles/blit_command_gles.cc index c9dd0f5d7a..d31c8212c0 100644 --- a/engine/src/flutter/impeller/renderer/backend/gles/blit_command_gles.cc +++ b/engine/src/flutter/impeller/renderer/backend/gles/blit_command_gles.cc @@ -372,6 +372,8 @@ bool BlitResizeTextureCommandGLES::Encode(const ReactorGLES& reactor) const { return false; } + destination->SetCoordinateSystem(source->GetCoordinateSystem()); + GLuint read_fbo = GL_NONE; GLuint draw_fbo = GL_NONE; fml::ScopedCleanupClosure delete_fbos([&gl, &read_fbo, &draw_fbo]() { diff --git a/engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.cc b/engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.cc index 18a5e1accb..2f3c488285 100644 --- a/engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.cc +++ b/engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.cc @@ -109,6 +109,10 @@ CapabilitiesGLES::CapabilitiesGLES(const ProcTableGLES& gl) { default_glyph_atlas_format_ = PixelFormat::kR8UNormInt; } + if (desc->GetGlVersion().major_version >= 3) { + supports_texture_to_texture_blits_ = true; + } + supports_framebuffer_fetch_ = desc->HasExtension(kFramebufferFetchExt); if (desc->HasExtension(kTextureBorderClampExt) || @@ -158,10 +162,7 @@ bool CapabilitiesGLES::SupportsSSBO() const { } bool CapabilitiesGLES::SupportsTextureToTextureBlits() const { - // TODO(158523): Switch this to true for improved performance - // on GLES 3.0+ devices. Note that this wasn't enabled because - // there were some rendering issues on some devices. - return false; + return supports_texture_to_texture_blits_; } bool CapabilitiesGLES::SupportsFramebufferFetch() const { diff --git a/engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.h b/engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.h index 199cdf35e0..fa39cfecab 100644 --- a/engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.h +++ b/engine/src/flutter/impeller/renderer/backend/gles/capabilities_gles.h @@ -131,6 +131,7 @@ class CapabilitiesGLES final ISize GetMaximumRenderPassAttachmentSize() const override; private: + bool supports_texture_to_texture_blits_ = false; bool supports_framebuffer_fetch_ = false; bool supports_decal_sampler_address_mode_ = false; bool supports_offscreen_msaa_ = false; diff --git a/engine/src/flutter/impeller/renderer/backend/gles/test/capabilities_unittests.cc b/engine/src/flutter/impeller/renderer/backend/gles/test/capabilities_unittests.cc index 9ae3611822..f93eab8605 100644 --- a/engine/src/flutter/impeller/renderer/backend/gles/test/capabilities_unittests.cc +++ b/engine/src/flutter/impeller/renderer/backend/gles/test/capabilities_unittests.cc @@ -17,7 +17,7 @@ TEST(CapabilitiesGLES, CanInitializeWithDefaults) { EXPECT_FALSE(capabilities->SupportsOffscreenMSAA()); EXPECT_FALSE(capabilities->SupportsSSBO()); - EXPECT_FALSE(capabilities->SupportsTextureToTextureBlits()); + EXPECT_TRUE(capabilities->SupportsTextureToTextureBlits()); EXPECT_FALSE(capabilities->SupportsFramebufferFetch()); EXPECT_FALSE(capabilities->SupportsCompute()); EXPECT_FALSE(capabilities->SupportsComputeSubgroups()); diff --git a/engine/src/flutter/impeller/renderer/blit_pass_unittests.cc b/engine/src/flutter/impeller/renderer/blit_pass_unittests.cc index ceae7e96c3..d8b2d1b7f6 100644 --- a/engine/src/flutter/impeller/renderer/blit_pass_unittests.cc +++ b/engine/src/flutter/impeller/renderer/blit_pass_unittests.cc @@ -3,6 +3,9 @@ // found in the LICENSE file. #include +#include "flutter/display_list/dl_builder.h" +#include "flutter/impeller/display_list/aiks_unittests.h" +#include "flutter/impeller/display_list/dl_image_impeller.h" #include "fml/mapping.h" #include "gtest/gtest.h" #include "impeller/base/validation.h" @@ -16,7 +19,12 @@ namespace impeller { namespace testing { -using BlitPassTest = PlaygroundTest; +using flutter::DisplayListBuilder; +using flutter::DlColor; +using flutter::DlImageSampling; +using flutter::DlPaint; + +using BlitPassTest = AiksTest; INSTANTIATE_PLAYGROUND_SUITE(BlitPassTest); TEST_P(BlitPassTest, BlitAcrossDifferentPixelFormatsFails) { @@ -230,5 +238,36 @@ TEST_P(BlitPassTest, CanResizeTextures) { EXPECT_TRUE(context->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok()); } +TEST_P(BlitPassTest, CanResizeTexturesPlayground) { + auto context = GetContext(); + auto cmd_buffer = context->CreateCommandBuffer(); + auto blit_pass = cmd_buffer->CreateBlitPass(); + + std::shared_ptr src = CreateTextureForFixture("kalimba.jpg"); + + TextureDescriptor dst_format; + dst_format.storage_mode = StorageMode::kDevicePrivate; + dst_format.format = PixelFormat::kR8G8B8A8UNormInt; + dst_format.size = {src->GetSize().width / 2, src->GetSize().height}; + dst_format.usage = TextureUsage::kShaderRead | TextureUsage::kShaderWrite; + auto dst = context->GetResourceAllocator()->CreateTexture(dst_format); + + ASSERT_TRUE(dst); + ASSERT_TRUE(src); + + EXPECT_TRUE(blit_pass->ResizeTexture(src, dst)); + EXPECT_TRUE(blit_pass->EncodeCommands(GetContext()->GetResourceAllocator())); + EXPECT_TRUE(context->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok()); + + DisplayListBuilder builder; + builder.Scale(GetContentScale().x, GetContentScale().y); + DlPaint paint; + paint.setColor(DlColor::kRed()); + auto image = DlImageImpeller::Make(dst); + builder.DrawImage(image, SkPoint::Make(100.0, 100.0), + DlImageSampling::kNearestNeighbor, &paint); + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + } // namespace testing } // namespace impeller diff --git a/engine/src/flutter/lib/ui/painting/image_decoder_impeller.cc b/engine/src/flutter/lib/ui/painting/image_decoder_impeller.cc index 656b3a4aa1..0b67df5216 100644 --- a/engine/src/flutter/lib/ui/painting/image_decoder_impeller.cc +++ b/engine/src/flutter/lib/ui/painting/image_decoder_impeller.cc @@ -243,7 +243,7 @@ DecompressResult ImageDecoderImpeller::DecompressTexture( !capabilities->SupportsTextureToTextureBlits()) { //---------------------------------------------------------------------------- /// 2. If the decoded image isn't the requested target size and the src size - /// exceeds the device max texture size, perform a slow CPU reisze. + /// exceeds the device max texture size, perform a slow CPU resize. /// TRACE_EVENT0("impeller", "SlowCPUDecodeScale"); const auto scaled_image_info = image_info.makeDimensions(target_size); diff --git a/engine/src/flutter/shell/platform/android/android_context_gl_impeller.cc b/engine/src/flutter/shell/platform/android/android_context_gl_impeller.cc index c497565c7f..4397976811 100644 --- a/engine/src/flutter/shell/platform/android/android_context_gl_impeller.cc +++ b/engine/src/flutter/shell/platform/android/android_context_gl_impeller.cc @@ -92,7 +92,7 @@ AndroidContextGLImpeller::AndroidContextGLImpeller( } impeller::egl::ConfigDescriptor desc; - desc.api = impeller::egl::API::kOpenGLES2; + desc.api = impeller::egl::API::kOpenGLES3; desc.color_format = impeller::egl::ColorFormat::kRGBA8888; desc.depth_bits = impeller::egl::DepthBits::kTwentyFour; desc.stencil_bits = impeller::egl::StencilBits::kEight; @@ -101,6 +101,12 @@ AndroidContextGLImpeller::AndroidContextGLImpeller( desc.surface_type = impeller::egl::SurfaceType::kWindow; std::unique_ptr onscreen_config = display_->ChooseConfig(desc); + + if (!onscreen_config) { + desc.api = impeller::egl::API::kOpenGLES2; + onscreen_config = display_->ChooseConfig(desc); + } + if (!onscreen_config) { // Fallback for Android emulator. desc.samples = impeller::egl::Samples::kOne; diff --git a/engine/src/flutter/shell/platform/android/android_context_gl_impeller_unittests.cc b/engine/src/flutter/shell/platform/android/android_context_gl_impeller_unittests.cc index 509c8df6f0..b74c068de0 100644 --- a/engine/src/flutter/shell/platform/android/android_context_gl_impeller_unittests.cc +++ b/engine/src/flutter/shell/platform/android/android_context_gl_impeller_unittests.cc @@ -97,28 +97,38 @@ TEST_F(AndroidContextGLImpellerTest, FallbackForEmulator) { auto display = std::make_unique(); EXPECT_CALL(*display, IsValid).WillRepeatedly(Return(true)); std::unique_ptr first_result; - auto second_result = - std::make_unique(ConfigDescriptor(), window_egl_config); + std::unique_ptr second_result; auto third_result = + std::make_unique(ConfigDescriptor(), window_egl_config); + auto fourth_result = std::make_unique(ConfigDescriptor(), pbuffer_egl_config); EXPECT_CALL( *display, ChooseConfig(Matcher(AllOf( + Field(&ConfigDescriptor::api, impeller::egl::API::kOpenGLES3), Field(&ConfigDescriptor::samples, impeller::egl::Samples::kFour), Field(&ConfigDescriptor::surface_type, impeller::egl::SurfaceType::kWindow))))) .WillOnce(Return(ByMove(std::move(first_result)))); + EXPECT_CALL( + *display, + ChooseConfig(Matcher(AllOf( + Field(&ConfigDescriptor::api, impeller::egl::API::kOpenGLES2), + Field(&ConfigDescriptor::samples, impeller::egl::Samples::kFour), + Field(&ConfigDescriptor::surface_type, + impeller::egl::SurfaceType::kWindow))))) + .WillOnce(Return(ByMove(std::move(second_result)))); EXPECT_CALL( *display, ChooseConfig(Matcher( AllOf(Field(&ConfigDescriptor::samples, impeller::egl::Samples::kOne), Field(&ConfigDescriptor::surface_type, impeller::egl::SurfaceType::kWindow))))) - .WillOnce(Return(ByMove(std::move(second_result)))); + .WillOnce(Return(ByMove(std::move(third_result)))); EXPECT_CALL(*display, ChooseConfig(Matcher( Field(&ConfigDescriptor::surface_type, impeller::egl::SurfaceType::kPBuffer)))) - .WillOnce(Return(ByMove(std::move(third_result)))); + .WillOnce(Return(ByMove(std::move(fourth_result)))); ON_CALL(*display, ChooseConfig(_)) .WillByDefault(Return(ByMove(std::unique_ptr()))); auto context = diff --git a/engine/src/flutter/testing/impeller_golden_tests_output.txt b/engine/src/flutter/testing/impeller_golden_tests_output.txt index f7f9601873..7a7372d3fb 100644 --- a/engine/src/flutter/testing/impeller_golden_tests_output.txt +++ b/engine/src/flutter/testing/impeller_golden_tests_output.txt @@ -951,6 +951,9 @@ impeller_Play_AiksTest_VerticesGeometryUVPositionDataWithTranslate_Vulkan.png impeller_Play_AiksTest_VerticesGeometryUVPositionData_Metal.png impeller_Play_AiksTest_VerticesGeometryUVPositionData_OpenGLES.png impeller_Play_AiksTest_VerticesGeometryUVPositionData_Vulkan.png +impeller_Play_BlitPassTest_CanResizeTexturesPlayground_Metal.png +impeller_Play_BlitPassTest_CanResizeTexturesPlayground_OpenGLES.png +impeller_Play_BlitPassTest_CanResizeTexturesPlayground_Vulkan.png impeller_Play_DlGoldenTest_Bug147807_Metal.png impeller_Play_DlGoldenTest_Bug147807_OpenGLES.png impeller_Play_DlGoldenTest_Bug147807_Vulkan.png