diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index b8e32aa31564f..b9616d7a43ae7 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -4045,6 +4045,7 @@ ORIGIN: ../../../flutter/vulkan/procs/vulkan_interface.cc + ../../../flutter/LIC ORIGIN: ../../../flutter/vulkan/procs/vulkan_interface.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/vulkan/procs/vulkan_proc_table.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/vulkan/procs/vulkan_proc_table.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/vulkan/swiftshader_path.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/vulkan/vulkan_application.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/vulkan/vulkan_application.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/vulkan/vulkan_backbuffer.cc + ../../../flutter/LICENSE @@ -6832,6 +6833,7 @@ FILE: ../../../flutter/vulkan/procs/vulkan_interface.cc FILE: ../../../flutter/vulkan/procs/vulkan_interface.h FILE: ../../../flutter/vulkan/procs/vulkan_proc_table.cc FILE: ../../../flutter/vulkan/procs/vulkan_proc_table.h +FILE: ../../../flutter/vulkan/swiftshader_path.h FILE: ../../../flutter/vulkan/vulkan_application.cc FILE: ../../../flutter/vulkan/vulkan_application.h FILE: ../../../flutter/vulkan/vulkan_backbuffer.cc diff --git a/impeller/BUILD.gn b/impeller/BUILD.gn index 696226f8fe334..c02ccd0558455 100644 --- a/impeller/BUILD.gn +++ b/impeller/BUILD.gn @@ -34,6 +34,10 @@ config("impeller_public_config") { defines += [ "IMPELLER_ENABLE_VULKAN=1" ] } + if (impeller_enable_vulkan_playgrounds) { + defines += [ "IMPELLER_ENABLE_VULKAN_PLAYGROUNDS=1" ] + } + if (impeller_trace_all_gl_calls) { defines += [ "IMPELLER_TRACE_ALL_GL_CALLS" ] } diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index d4d3829972fea..2308d5385fb4a 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -8,6 +8,7 @@ #include #include "flutter/fml/logging.h" +#include "flutter/fml/trace_event.h" #include "impeller/aiks/image_filter.h" #include "impeller/aiks/paint_pass_delegate.h" #include "impeller/entity/contents/atlas_contents.h" @@ -536,6 +537,7 @@ size_t Canvas::GetClipDepth() const { void Canvas::SaveLayer(const Paint& paint, std::optional bounds, const std::shared_ptr& backdrop_filter) { + TRACE_EVENT0("flutter", "Canvas::saveLayer"); Save(true, paint.blend_mode, backdrop_filter); auto& new_layer_pass = GetCurrentPass(); diff --git a/impeller/base/validation.cc b/impeller/base/validation.cc index bb41c50fec462..bbfd7efda3710 100644 --- a/impeller/base/validation.cc +++ b/impeller/base/validation.cc @@ -48,7 +48,7 @@ void ImpellerValidationBreak(const char* message) { } else { FML_LOG(ERROR) << stream.str(); } -#endif // IMPELLER_DEBUG +#endif // IMPELLER_ENABLE_VALIDATION } } // namespace impeller diff --git a/impeller/playground/playground.cc b/impeller/playground/playground.cc index 93eb4eb3ce204..8d2f591a561dd 100644 --- a/impeller/playground/playground.cc +++ b/impeller/playground/playground.cc @@ -102,7 +102,7 @@ bool Playground::SupportsBackend(PlaygroundBackend backend) { return false; #endif // IMPELLER_ENABLE_OPENGLES case PlaygroundBackend::kVulkan: -#if IMPELLER_ENABLE_VULKAN +#if IMPELLER_ENABLE_VULKAN && IMPELLER_ENABLE_VULKAN_PLAYGROUNDS return true; #else // IMPELLER_ENABLE_VULKAN return false; diff --git a/impeller/renderer/backend/vulkan/allocator_vk.cc b/impeller/renderer/backend/vulkan/allocator_vk.cc index 3fc4f2f99ca5a..f90ee4bc447d6 100644 --- a/impeller/renderer/backend/vulkan/allocator_vk.cc +++ b/impeller/renderer/backend/vulkan/allocator_vk.cc @@ -265,6 +265,7 @@ class AllocatedTextureSourceVK final : public TextureSourceVK { vk::Device device, bool supports_memoryless_textures) : TextureSourceVK(desc), resource_(std::move(resource_manager)) { + FML_DCHECK(desc.format != PixelFormat::kUnknown); TRACE_EVENT0("impeller", "CreateDeviceTexture"); vk::ImageCreateInfo image_info; image_info.flags = ToVKImageCreateFlags(desc.type); diff --git a/impeller/renderer/backend/vulkan/blit_command_vk_unittests.cc b/impeller/renderer/backend/vulkan/blit_command_vk_unittests.cc index 9b911c66cef17..260c9e4a45861 100644 --- a/impeller/renderer/backend/vulkan/blit_command_vk_unittests.cc +++ b/impeller/renderer/backend/vulkan/blit_command_vk_unittests.cc @@ -16,9 +16,11 @@ TEST(BlitCommandVkTest, BlitCopyTextureToTextureCommandVK) { auto encoder = std::make_unique(context)->Create(); BlitCopyTextureToTextureCommandVK cmd; cmd.source = context->GetResourceAllocator()->CreateTexture({ + .format = PixelFormat::kR8G8B8A8UNormInt, .size = ISize(100, 100), }); cmd.destination = context->GetResourceAllocator()->CreateTexture({ + .format = PixelFormat::kR8G8B8A8UNormInt, .size = ISize(100, 100), }); bool result = cmd.Encode(*encoder.get()); @@ -32,6 +34,7 @@ TEST(BlitCommandVkTest, BlitCopyTextureToBufferCommandVK) { auto encoder = std::make_unique(context)->Create(); BlitCopyTextureToBufferCommandVK cmd; cmd.source = context->GetResourceAllocator()->CreateTexture({ + .format = PixelFormat::kR8G8B8A8UNormInt, .size = ISize(100, 100), }); cmd.destination = context->GetResourceAllocator()->CreateBuffer({ @@ -48,6 +51,7 @@ TEST(BlitCommandVkTest, BlitCopyBufferToTextureCommandVK) { auto encoder = std::make_unique(context)->Create(); BlitCopyBufferToTextureCommandVK cmd; cmd.destination = context->GetResourceAllocator()->CreateTexture({ + .format = PixelFormat::kR8G8B8A8UNormInt, .size = ISize(100, 100), }); cmd.source = context->GetResourceAllocator() @@ -66,6 +70,7 @@ TEST(BlitCommandVkTest, BlitGenerateMipmapCommandVK) { auto encoder = std::make_unique(context)->Create(); BlitGenerateMipmapCommandVK cmd; cmd.texture = context->GetResourceAllocator()->CreateTexture({ + .format = PixelFormat::kR8G8B8A8UNormInt, .size = ISize(100, 100), .mip_count = 2, }); diff --git a/impeller/renderer/backend/vulkan/surface_context_vk.cc b/impeller/renderer/backend/vulkan/surface_context_vk.cc index 2e20d2af5cbe6..afc1407f6f3f5 100644 --- a/impeller/renderer/backend/vulkan/surface_context_vk.cc +++ b/impeller/renderer/backend/vulkan/surface_context_vk.cc @@ -63,6 +63,10 @@ bool SurfaceContextVK::SetWindowSurface(vk::UniqueSurfaceKHR surface) { VALIDATION_LOG << "Could not create swapchain."; return false; } + if (!swapchain->IsValid()) { + VALIDATION_LOG << "Could not create valid swapchain."; + return false; + } swapchain_ = std::move(swapchain); return true; } diff --git a/impeller/renderer/backend/vulkan/swapchain_impl_vk.cc b/impeller/renderer/backend/vulkan/swapchain_impl_vk.cc index 0af88001b8e95..dcd5d1c50b593 100644 --- a/impeller/renderer/backend/vulkan/swapchain_impl_vk.cc +++ b/impeller/renderer/backend/vulkan/swapchain_impl_vk.cc @@ -142,6 +142,7 @@ SwapchainImplVK::SwapchainImplVK( vk::SwapchainKHR old_swapchain, vk::SurfaceTransformFlagBitsKHR last_transform) { if (!context) { + VALIDATION_LOG << "Cannot create a swapchain without a context."; return; } diff --git a/impeller/renderer/backend/vulkan/swapchain_vk.cc b/impeller/renderer/backend/vulkan/swapchain_vk.cc index 0a09a9eb371e0..c5399ce4835e7 100644 --- a/impeller/renderer/backend/vulkan/swapchain_vk.cc +++ b/impeller/renderer/backend/vulkan/swapchain_vk.cc @@ -5,6 +5,7 @@ #include "impeller/renderer/backend/vulkan/swapchain_vk.h" #include "flutter/fml/trace_event.h" +#include "impeller/base/validation.h" #include "impeller/renderer/backend/vulkan/swapchain_impl_vk.h" namespace impeller { @@ -14,6 +15,7 @@ std::shared_ptr SwapchainVK::Create( vk::UniqueSurfaceKHR surface) { auto impl = SwapchainImplVK::Create(context, std::move(surface)); if (!impl || !impl->IsValid()) { + VALIDATION_LOG << "Failed to create SwapchainVK implementation."; return nullptr; } return std::shared_ptr(new SwapchainVK(std::move(impl))); diff --git a/impeller/tools/impeller.gni b/impeller/tools/impeller.gni index 35758f3013b46..15caa5631c472 100644 --- a/impeller/tools/impeller.gni +++ b/impeller/tools/impeller.gni @@ -22,7 +22,14 @@ declare_args() { (is_linux || is_win || is_android) && target_os != "fuchsia" # Whether the Vulkan backend is enabled. - impeller_enable_vulkan = + impeller_enable_vulkan = (is_linux || is_win || is_android || + enable_unittests) && target_os != "fuchsia" + + # Whether playgrounds should run with Vulkan. + # + # impeller_enable_vulkan may be true in build environments that run tests but + # do not have a Vulkan ICD present. + impeller_enable_vulkan_playgrounds = (is_linux || is_win || is_android) && target_os != "fuchsia" # Whether to use a prebuilt impellerc. diff --git a/lib/gpu/context.cc b/lib/gpu/context.cc index 34418320b5ddc..7539f0cb7300a 100644 --- a/lib/gpu/context.cc +++ b/lib/gpu/context.cc @@ -55,7 +55,8 @@ Dart_Handle InternalFlutterGpu_Context_InitializeDefault(Dart_Handle wrapper) { // Grab the Impeller context from the IO manager. std::promise> context_promise; auto impeller_context_future = context_promise.get_future(); - dart_state->GetTaskRunners().GetIOTaskRunner()->PostTask( + fml::TaskRunner::RunNowOrPostTask( + dart_state->GetTaskRunners().GetIOTaskRunner(), fml::MakeCopyable([promise = std::move(context_promise), io_manager = dart_state->GetIOManager()]() mutable { promise.set_value(io_manager ? io_manager->GetImpellerContext() diff --git a/lib/ui/fixtures/impeller_2_dispose_op_restore_previous.apng.67.png b/lib/ui/fixtures/impeller_2_dispose_op_restore_previous.apng.67.png new file mode 100644 index 0000000000000..bdec9bc8f1499 Binary files /dev/null and b/lib/ui/fixtures/impeller_2_dispose_op_restore_previous.apng.67.png differ diff --git a/lib/ui/fixtures/impeller_2_dispose_op_restore_previous.apng.68.png b/lib/ui/fixtures/impeller_2_dispose_op_restore_previous.apng.68.png new file mode 100644 index 0000000000000..6ade80e00e468 Binary files /dev/null and b/lib/ui/fixtures/impeller_2_dispose_op_restore_previous.apng.68.png differ diff --git a/lib/ui/fixtures/impeller_2_dispose_op_restore_previous.apng.69.png b/lib/ui/fixtures/impeller_2_dispose_op_restore_previous.apng.69.png new file mode 100644 index 0000000000000..c3006d0c2f89b Binary files /dev/null and b/lib/ui/fixtures/impeller_2_dispose_op_restore_previous.apng.69.png differ diff --git a/lib/ui/fixtures/impeller_four_frame_with_reuse_end.png b/lib/ui/fixtures/impeller_four_frame_with_reuse_end.png new file mode 100644 index 0000000000000..7c67236810621 Binary files /dev/null and b/lib/ui/fixtures/impeller_four_frame_with_reuse_end.png differ diff --git a/lib/ui/fixtures/impeller_heart_end.png b/lib/ui/fixtures/impeller_heart_end.png new file mode 100644 index 0000000000000..cd33ff064c605 Binary files /dev/null and b/lib/ui/fixtures/impeller_heart_end.png differ diff --git a/shell/common/shell.cc b/shell/common/shell.cc index fc006308dec19..a6ba487b581f7 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -1695,6 +1695,11 @@ bool Shell::OnServiceProtocolScreenshotSKP( const ServiceProtocol::Handler::ServiceProtocolMap& params, rapidjson::Document* response) { FML_DCHECK(task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread()); + if (settings_.enable_impeller) { + ServiceProtocolFailureError( + response, "Cannot capture SKP screenshot with Impeller enabled."); + return false; + } auto screenshot = rasterizer_->ScreenshotLastLayerTree( Rasterizer::ScreenshotType::SkiaPicture, true); if (screenshot.data) { diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index 38170118e2072..d19e5cb2bcaff 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -17,12 +17,8 @@ #if OS_FUCHSIA #define VULKAN_SO_PATH "libvulkan.so" -#elif FML_OS_MACOSX -#define VULKAN_SO_PATH "libvk_swiftshader.dylib" -#elif FML_OS_WIN -#define VULKAN_SO_PATH "vk_swiftshader.dll" #else -#define VULKAN_SO_PATH "libvk_swiftshader.so" +#include "flutter/vulkan/swiftshader_path.h" #endif namespace flutter { diff --git a/shell/gpu/gpu_surface_vulkan.cc b/shell/gpu/gpu_surface_vulkan.cc index a8976d677afd0..63f1359722c17 100644 --- a/shell/gpu/gpu_surface_vulkan.cc +++ b/shell/gpu/gpu_surface_vulkan.cc @@ -104,6 +104,7 @@ sk_sp GPUSurfaceVulkan::CreateSurfaceFromVulkanImage( const VkImage image, const VkFormat format, const SkISize& size) { +#ifdef SK_VULKAN GrVkImageInfo image_info = { .fImage = image, .fImageTiling = VK_IMAGE_TILING_OPTIMAL, @@ -130,6 +131,9 @@ sk_sp GPUSurfaceVulkan::CreateSurfaceFromVulkanImage( SkColorSpace::MakeSRGB(), // color space &surface_properties // surface properties ); +#else + return nullptr; +#endif // SK_VULKAN } SkColorType GPUSurfaceVulkan::ColorTypeFromFormat(const VkFormat format) { diff --git a/shell/gpu/gpu_surface_vulkan_impeller.cc b/shell/gpu/gpu_surface_vulkan_impeller.cc index 3b6ec9d876ec0..917b5f0e6e11d 100644 --- a/shell/gpu/gpu_surface_vulkan_impeller.cc +++ b/shell/gpu/gpu_surface_vulkan_impeller.cc @@ -60,6 +60,11 @@ std::unique_ptr GPUSurfaceVulkanImpeller::AcquireFrame( auto& context_vk = impeller::SurfaceContextVK::Cast(*impeller_context_); std::unique_ptr surface = context_vk.AcquireNextSurface(); + if (!surface) { + FML_LOG(ERROR) << "No surface available."; + return nullptr; + } + SurfaceFrame::SubmitCallback submit_callback = fml::MakeCopyable([renderer = impeller_renderer_, // aiks_context = aiks_context_, // diff --git a/shell/testing/BUILD.gn b/shell/testing/BUILD.gn index ec6400ce0763a..8f4572310c519 100644 --- a/shell/testing/BUILD.gn +++ b/shell/testing/BUILD.gn @@ -3,6 +3,15 @@ # found in the LICENSE file. import("//build/fuchsia/sdk.gni") +import("//flutter/impeller/tools/impeller.gni") +import("//flutter/shell/gpu/gpu.gni") + +shell_gpu_configuration("tester_gpu_configuration") { + enable_software = true + enable_gl = true + enable_vulkan = true + enable_metal = false +} executable("testing") { output_name = "flutter_tester" @@ -13,8 +22,9 @@ executable("testing") { ] sources = [ "tester_main.cc" ] + libs = [] if (is_win) { - libs = [ + libs += [ "psapi.lib", "user32.lib", "FontSub.lib", @@ -36,6 +46,14 @@ executable("testing") { "//third_party/skia", ] + if (impeller_supports_rendering) { + deps += [ + ":tester_gpu_configuration", + "//flutter/impeller", + "//third_party/swiftshader", + ] + } + metadata = { entitlement_file_path = [ "flutter_tester" ] } diff --git a/shell/testing/tester_main.cc b/shell/testing/tester_main.cc index 310ce62e01430..9c0059b612160 100644 --- a/shell/testing/tester_main.cc +++ b/shell/testing/tester_main.cc @@ -29,6 +29,46 @@ #include "third_party/dart/runtime/include/dart_api.h" #include "third_party/skia/include/core/SkSurface.h" +#if IMPELLER_SUPPORTS_RENDERING +#include // nogncheck +#include "flutter/vulkan/procs/vulkan_proc_table.h" // nogncheck +#include "flutter/vulkan/swiftshader_path.h" // nogncheck +#include "impeller/entity/vk/entity_shaders_vk.h" // nogncheck +#include "impeller/entity/vk/modern_shaders_vk.h" // nogncheck +#include "impeller/renderer/backend/vulkan/context_vk.h" // nogncheck +#include "impeller/renderer/backend/vulkan/surface_context_vk.h" // nogncheck +#include "impeller/renderer/context.h" // nogncheck +#include "impeller/renderer/vk/compute_shaders_vk.h" // nogncheck +#include "shell/gpu/gpu_surface_vulkan_impeller.h" // nogncheck +#if IMPELLER_ENABLE_3D +#include "impeller/scene/shaders/vk/scene_shaders_vk.h" // nogncheck +#endif // IMPELLER_ENABLE_3D + +static std::vector> ShaderLibraryMappings() { + return { + std::make_shared(impeller_entity_shaders_vk_data, + impeller_entity_shaders_vk_length), + std::make_shared( + impeller_modern_shaders_vk_data, impeller_modern_shaders_vk_length), +#if IMPELLER_ENABLE_3D + std::make_shared( + impeller_scene_shaders_vk_data, impeller_scene_shaders_vk_length), +#endif // IMPELLER_ENABLE_3D + std::make_shared( + impeller_compute_shaders_vk_data, + impeller_compute_shaders_vk_length), + }; +} + +struct ImpellerVulkanContextHolder { + fml::RefPtr vulkan_proc_table; + std::shared_ptr context; + std::shared_ptr surface_context; +}; +#else +struct ImpellerVulkanContextHolder {}; +#endif // IMPELLER_SUPPORTS_RENDERING + #if defined(FML_OS_WIN) #include #endif // defined(FML_OS_WIN) @@ -81,11 +121,41 @@ class TesterGPUSurfaceSoftware : public GPUSurfaceSoftware { class TesterPlatformView : public PlatformView, public GPUSurfaceSoftwareDelegate { public: - TesterPlatformView(Delegate& delegate, const TaskRunners& task_runners) - : PlatformView(delegate, task_runners) {} + TesterPlatformView(Delegate& delegate, + const TaskRunners& task_runners, + ImpellerVulkanContextHolder impeller_context_holder) + : PlatformView(delegate, task_runners), + impeller_context_holder_(std::move(impeller_context_holder)) {} + + ~TesterPlatformView() { +#if IMPELLER_SUPPORTS_RENDERING + if (impeller_context_holder_.context) { + impeller_context_holder_.context->Shutdown(); + } +#endif + } + + // |PlatformView| + std::shared_ptr GetImpellerContext() const override { +#if IMPELLER_SUPPORTS_RENDERING + return std::static_pointer_cast( + impeller_context_holder_.context); +#else + return nullptr; +#endif // IMPELLER_SUPPORTS_RENDERING + } // |PlatformView| std::unique_ptr CreateRenderingSurface() override { +#if IMPELLER_SUPPORTS_RENDERING + if (delegate_.OnPlatformViewGetSettings().enable_impeller) { + FML_DCHECK(impeller_context_holder_.context); + auto surface = std::make_unique( + impeller_context_holder_.surface_context); + FML_DCHECK(surface->IsValid()); + return surface; + } +#endif // IMPELLER_SUPPORTS_RENDERING auto surface = std::make_unique( this, true /* render to surface */); FML_DCHECK(surface->IsValid()); @@ -126,6 +196,7 @@ class TesterPlatformView : public PlatformView, private: sk_sp sk_surface_ = nullptr; + [[maybe_unused]] ImpellerVulkanContextHolder impeller_context_holder_; std::shared_ptr external_view_embedder_ = std::make_shared(); }; @@ -235,10 +306,63 @@ int RunTester(const flutter::Settings& settings, io_task_runner // io ); + ImpellerVulkanContextHolder impeller_context_holder; + +#if IMPELLER_SUPPORTS_RENDERING + if (settings.enable_impeller) { + impeller_context_holder.vulkan_proc_table = + fml::MakeRefCounted(VULKAN_SO_PATH); + if (!impeller_context_holder.vulkan_proc_table + ->NativeGetInstanceProcAddr()) { + FML_LOG(ERROR) << "Could not load Swiftshader library."; + return EXIT_FAILURE; + } + impeller::ContextVK::Settings context_settings; + context_settings.proc_address_callback = + impeller_context_holder.vulkan_proc_table->NativeGetInstanceProcAddr(); + context_settings.shader_libraries_data = ShaderLibraryMappings(); + context_settings.cache_directory = fml::paths::GetCachesDirectory(); + context_settings.enable_validation = settings.enable_vulkan_validation; + + impeller_context_holder.context = + impeller::ContextVK::Create(std::move(context_settings)); + if (!impeller_context_holder.context || + !impeller_context_holder.context->IsValid()) { + VALIDATION_LOG << "Could not create Vulkan context."; + return EXIT_FAILURE; + } + + impeller::vk::SurfaceKHR vk_surface; + impeller::vk::HeadlessSurfaceCreateInfoEXT surface_create_info; + auto res = + impeller_context_holder.context->GetInstance().createHeadlessSurfaceEXT( + &surface_create_info, // surface create info + nullptr, // allocator + &vk_surface // surface + ); + if (res != impeller::vk::Result::eSuccess) { + VALIDATION_LOG << "Could not create surface for tester " + << impeller::vk::to_string(res); + return EXIT_FAILURE; + } + + impeller::vk::UniqueSurfaceKHR surface{ + vk_surface, impeller_context_holder.context->GetInstance()}; + impeller_context_holder.surface_context = + impeller_context_holder.context->CreateSurfaceContext(); + if (!impeller_context_holder.surface_context->SetWindowSurface( + std::move(surface))) { + VALIDATION_LOG << "Could not set up surface for context."; + return EXIT_FAILURE; + } + } +#endif // IMPELLER_SUPPORTS_RENDERING + Shell::CreateCallback on_create_platform_view = - [](Shell& shell) { - return std::make_unique(shell, - shell.GetTaskRunners()); + [impeller_context_holder = + std::move(impeller_context_holder)](Shell& shell) { + return std::make_unique( + shell, shell.GetTaskRunners(), impeller_context_holder); }; Shell::CreateCallback on_create_rasterizer = [](Shell& shell) { diff --git a/testing/dart/canvas_test.dart b/testing/dart/canvas_test.dart index 6732423695d2b..d317e2f13e420 100644 --- a/testing/dart/canvas_test.dart +++ b/testing/dart/canvas_test.dart @@ -12,6 +12,8 @@ import 'package:litetest/litetest.dart'; import 'package:path/path.dart' as path; import 'package:vector_math/vector_math_64.dart'; +import 'impeller_enabled.dart'; + typedef CanvasCallback = void Function(Canvas canvas); Future createImage(int width, int height) { @@ -192,7 +194,7 @@ void main() { final bool areEqual = await fuzzyGoldenImageCompare(image, 'canvas_test_toImage.png'); expect(areEqual, true); - }); + }, skip: impellerEnabled); Gradient makeGradient() { return Gradient.linear( @@ -213,7 +215,7 @@ void main() { final bool areEqual = await fuzzyGoldenImageCompare(image, 'canvas_test_dithered_gradient.png'); expect(areEqual, true); - }, skip: !Platform.isLinux); // https://github.com/flutter/flutter/issues/53784 + }, skip: !Platform.isLinux || impellerEnabled); // https://github.com/flutter/flutter/issues/53784 test('Null values allowed for drawAtlas methods', () async { final Image image = await createImage(100, 100); @@ -349,7 +351,7 @@ void main() { final bool areEqual = await fuzzyGoldenImageCompare(image, 'dotted_path_effect_mixed_with_stroked_geometry.png'); expect(areEqual, true); - }, skip: !Platform.isLinux); // https://github.com/flutter/flutter/issues/53784 + }, skip: !Platform.isLinux || impellerEnabled); // https://github.com/flutter/flutter/issues/53784 test('Gradients with matrices in Paragraphs render correctly', () async { final Image image = await toImage((Canvas canvas) { @@ -401,7 +403,7 @@ void main() { final bool areEqual = await fuzzyGoldenImageCompare(image, 'text_with_gradient_with_matrix.png'); expect(areEqual, true); - }, skip: !Platform.isLinux); // https://github.com/flutter/flutter/issues/53784 + }, skip: !Platform.isLinux || impellerEnabled); // https://github.com/flutter/flutter/issues/53784 test('toImageSync - too big', () async { PictureRecorder recorder = PictureRecorder(); @@ -417,6 +419,12 @@ void main() { recorder = PictureRecorder(); canvas = Canvas(recorder); + if (impellerEnabled) { + // Impeller tries to automagically scale this. See + // https://github.com/flutter/flutter/issues/128885 + canvas.drawImage(image, Offset.zero, Paint()); + return; + } // On a slower CI machine, the raster thread may get behind the UI thread // here. However, once the image is in an error state it will immediately // throw on subsequent attempts. diff --git a/testing/dart/codec_test.dart b/testing/dart/codec_test.dart index fb07a63f61a21..702a5fd14e016 100644 --- a/testing/dart/codec_test.dart +++ b/testing/dart/codec_test.dart @@ -9,6 +9,8 @@ import 'dart:ui' as ui; import 'package:litetest/litetest.dart'; import 'package:path/path.dart' as path; +import 'impeller_enabled.dart'; + void main() { test('Animation metadata', () async { @@ -43,7 +45,11 @@ void main() { await codec.getNextFrame(); fail('exception not thrown'); } on Exception catch (e) { - expect(e.toString(), contains('Codec failed')); + if (impellerEnabled) { + expect(e.toString(), contains('Could not decompress image.')); + } else { + expect(e.toString(), contains('Codec failed')); + } } }); @@ -145,8 +151,9 @@ void main() { final ui.Image image = frameInfo.image; final ByteData imageData = (await image.toByteData(format: ui.ImageByteFormat.png))!; + final String fileName = impellerEnabled ? 'impeller_four_frame_with_reuse_end.png' : 'four_frame_with_reuse_end.png'; final Uint8List goldenData = File( - path.join('flutter', 'lib', 'ui', 'fixtures', 'four_frame_with_reuse_end.png'), + path.join('flutter', 'lib', 'ui', 'fixtures', fileName), ).readAsBytesSync(); expect(imageData.buffer.asUint8List(), goldenData); @@ -170,8 +177,10 @@ void main() { final ui.Image image = frameInfo.image; final ByteData imageData = (await image.toByteData(format: ui.ImageByteFormat.png))!; + final String fileName = impellerEnabled ? 'impeller_heart_end.png' : 'heart_end.png'; + final Uint8List goldenData = File( - path.join('flutter', 'lib', 'ui', 'fixtures', 'heart_end.png'), + path.join('flutter', 'lib', 'ui', 'fixtures', fileName), ).readAsBytesSync(); expect(imageData.buffer.asUint8List(), goldenData); @@ -194,8 +203,10 @@ void main() { final ui.Image image = frameInfo.image; final ByteData imageData = (await image.toByteData(format: ui.ImageByteFormat.png))!; + final String fileName = impellerEnabled ? 'impeller_2_dispose_op_restore_previous.apng.$i.png' : '2_dispose_op_restore_previous.apng.$i.png'; + final Uint8List goldenData = File( - path.join('flutter', 'lib', 'ui', 'fixtures', '2_dispose_op_restore_previous.apng.$i.png'), + path.join('flutter', 'lib', 'ui', 'fixtures', fileName), ).readAsBytesSync(); expect(imageData.buffer.asUint8List(), goldenData); diff --git a/testing/dart/color_filter_test.dart b/testing/dart/color_filter_test.dart index e5553604da9b2..66ec9548ca58f 100644 --- a/testing/dart/color_filter_test.dart +++ b/testing/dart/color_filter_test.dart @@ -7,6 +7,8 @@ import 'dart:ui'; import 'package:litetest/litetest.dart'; +import 'impeller_enabled.dart'; + const Color transparent = Color(0x00000000); const Color red = Color(0xFFAA0000); const Color green = Color(0xFF00AA00); @@ -56,6 +58,11 @@ void main() { Uint32List bytes = await getBytesForPaint(paint); expect(bytes[0], greenRedColorBlend); + // TODO(135699): enable this + if (impellerEnabled) { + return; + } + paint.invertColors = true; bytes = await getBytesForPaint(paint); expect(bytes[0], greenRedColorBlendInverted); @@ -87,6 +94,11 @@ void main() { Uint32List bytes = await getBytesForPaint(paint); expect(bytes[0], greenGreyscaled); + // TODO(135699): enable this + if (impellerEnabled) { + return; + } + paint.invertColors = true; bytes = await getBytesForPaint(paint); expect(bytes[0], greenInvertedGreyscaled); @@ -118,6 +130,10 @@ void main() { Uint32List bytes = await getBytesForPaint(paint); expect(bytes[0], greenLinearToSrgbGamma); + // TODO(135699): enable this + if (impellerEnabled) { + return; + } paint.invertColors = true; bytes = await getBytesForPaint(paint); expect(bytes[0], greenLinearToSrgbGammaInverted); @@ -131,6 +147,11 @@ void main() { Uint32List bytes = await getBytesForPaint(paint); expect(bytes[0], greenSrgbToLinearGamma); + // TODO(135699): enable this + if (impellerEnabled) { + return; + } + paint.invertColors = true; bytes = await getBytesForPaint(paint); expect(bytes[0], greenSrgbToLinearGammaInverted); diff --git a/testing/dart/encoding_test.dart b/testing/dart/encoding_test.dart index 9ca46b9306d02..2aa426a108100 100644 --- a/testing/dart/encoding_test.dart +++ b/testing/dart/encoding_test.dart @@ -10,6 +10,8 @@ import 'dart:ui'; import 'package:litetest/litetest.dart'; import 'package:path/path.dart' as path; +import 'impeller_enabled.dart'; + const int _kWidth = 10; const int _kRadius = 2; @@ -18,6 +20,10 @@ const Color _kGreen = Color.fromRGBO(0, 255, 0, 1.0); void main() { test('decodeImageFromPixels float32', () async { + if (impellerEnabled) { + print('Disabled on Impeller - https://github.com/flutter/flutter/issues/135702'); + return; + } const int width = 2; const int height = 2; final Float32List pixels = Float32List(width * height * 4); @@ -91,6 +97,10 @@ void main() { }); test('Image.toByteData Unmodified format works with grayscale images', () async { + if (impellerEnabled) { + print('Disabled on Impeller - https://github.com/flutter/flutter/issues/135706'); + return; + } final Image image = await GrayscaleImage.load(); final ByteData data = (await image.toByteData(format: ImageByteFormat.rawUnmodified))!; final Uint8List bytes = data.buffer.asUint8List(); @@ -99,6 +109,10 @@ void main() { }); test('Image.toByteData PNG format works with simple image', () async { + if (impellerEnabled) { + print('Disabled on Impeller - https://github.com/flutter/flutter/issues/135706'); + return; + } final Image image = await Square4x4Image.image; final ByteData data = (await image.toByteData(format: ImageByteFormat.png))!; final List expected = await readFile('square.png'); diff --git a/testing/dart/fragment_shader_test.dart b/testing/dart/fragment_shader_test.dart index e97eb5128f6e5..da34695df7814 100644 --- a/testing/dart/fragment_shader_test.dart +++ b/testing/dart/fragment_shader_test.dart @@ -12,6 +12,7 @@ import 'dart:ui'; import 'package:litetest/litetest.dart'; import 'package:path/path.dart' as path; +import 'impeller_enabled.dart'; import 'shader_test_file_utils.dart'; void main() async { @@ -172,6 +173,10 @@ void main() async { }); test('FragmentShader simple shader renders correctly', () async { + if (impellerEnabled) { + print('Skipped for Impeller - https://github.com/flutter/flutter/issues/122823'); + return; + } final FragmentProgram program = await FragmentProgram.fromAsset( 'functions.frag.iplr', ); @@ -182,6 +187,10 @@ void main() async { }); test('Reused FragmentShader simple shader renders correctly', () async { + if (impellerEnabled) { + print('Skipped for Impeller - https://github.com/flutter/flutter/issues/122823'); + return; + } final FragmentProgram program = await FragmentProgram.fromAsset( 'functions.frag.iplr', ); @@ -196,6 +205,10 @@ void main() async { }); test('FragmentShader blue-green image renders green', () async { + if (impellerEnabled) { + print('Skipped for Impeller - https://github.com/flutter/flutter/issues/122823'); + return; + } final FragmentProgram program = await FragmentProgram.fromAsset( 'blue_green_sampler.frag.iplr', ); @@ -208,6 +221,10 @@ void main() async { }); test('FragmentShader blue-green image renders green - GPU image', () async { + if (impellerEnabled) { + print('Skipped for Impeller - https://github.com/flutter/flutter/issues/122823'); + return; + } final FragmentProgram program = await FragmentProgram.fromAsset( 'blue_green_sampler.frag.iplr', ); @@ -220,6 +237,10 @@ void main() async { }); test('FragmentShader with uniforms renders correctly', () async { + if (impellerEnabled) { + print('Skipped for Impeller - https://github.com/flutter/flutter/issues/122823'); + return; + } final FragmentProgram program = await FragmentProgram.fromAsset( 'uniforms.frag.iplr', ); @@ -246,6 +267,10 @@ void main() async { }); test('FragmentShader shader with array uniforms renders correctly', () async { + if (impellerEnabled) { + print('Skipped for Impeller - https://github.com/flutter/flutter/issues/122823'); + return; + } final FragmentProgram program = await FragmentProgram.fromAsset( 'uniform_arrays.frag.iplr', ); @@ -260,6 +285,10 @@ void main() async { }); test('FragmentShader The ink_sparkle shader is accepted', () async { + if (impellerEnabled) { + print('Skipped for Impeller - https://github.com/flutter/flutter/issues/122823'); + return; + } final FragmentProgram program = await FragmentProgram.fromAsset( 'ink_sparkle.frag.iplr', ); @@ -273,6 +302,10 @@ void main() async { }); test('FragmentShader Uniforms are sorted correctly', () async { + if (impellerEnabled) { + print('Skipped for Impeller - https://github.com/flutter/flutter/issues/122823'); + return; + } final FragmentProgram program = await FragmentProgram.fromAsset( 'uniforms_sorted.frag.iplr', ); @@ -314,6 +347,10 @@ void main() async { }); test('FragmentShader user defined functions do not redefine builtins', () async { + if (impellerEnabled) { + print('Skipped for Impeller - https://github.com/flutter/flutter/issues/122823'); + return; + } final FragmentProgram program = await FragmentProgram.fromAsset( 'no_builtin_redefinition.frag.iplr', ); @@ -324,6 +361,10 @@ void main() async { }); test('FragmentShader fromAsset accepts a shader with no uniforms', () async { + if (impellerEnabled) { + print('Skipped for Impeller - https://github.com/flutter/flutter/issues/122823'); + return; + } final FragmentProgram program = await FragmentProgram.fromAsset( 'no_uniforms.frag.iplr', ); @@ -332,6 +373,11 @@ void main() async { shader.dispose(); }); + if (impellerEnabled) { + print('Skipped for Impeller - https://github.com/flutter/flutter/issues/122823'); + return; + } + // Test all supported GLSL ops. See lib/spirv/lib/src/constants.dart final Map iplrSupportedGLSLOpShaders = await _loadShaderAssets( path.join('supported_glsl_op_shaders', 'iplr'), diff --git a/testing/dart/gpu_test.dart b/testing/dart/gpu_test.dart index 0c96b6646dc0b..9d65c8ed4a66e 100644 --- a/testing/dart/gpu_test.dart +++ b/testing/dart/gpu_test.dart @@ -7,6 +7,8 @@ import 'package:litetest/litetest.dart'; import '../../lib/gpu/lib/gpu.dart' as gpu; +import 'impeller_enabled.dart'; + void main() { // TODO(131346): Remove this once we migrate the Dart GPU API into this space. test('smoketest', () async { @@ -25,9 +27,14 @@ void main() { test('gpu.context throws exception for incompatible embedders', () async { try { // ignore: unnecessary_statements - gpu.gpuContext; // Force the - fail('Exception not thrown'); + gpu.gpuContext; // Force the context to instantiate. + if (!impellerEnabled) { + fail('Exception not thrown, but no Impeller context available.'); + } } catch (e) { + if (impellerEnabled) { + fail('Exception thrown even though Impeller is enabled.'); + } expect( e.toString(), contains( diff --git a/testing/dart/image_filter_test.dart b/testing/dart/image_filter_test.dart index 0fa8651656300..0a79513d99430 100644 --- a/testing/dart/image_filter_test.dart +++ b/testing/dart/image_filter_test.dart @@ -7,6 +7,8 @@ import 'dart:ui'; import 'package:litetest/litetest.dart'; +import 'impeller_enabled.dart'; + const Color red = Color(0xFFAA0000); const Color green = Color(0xFF00AA00); @@ -174,6 +176,10 @@ void main() { } test('ImageFilter - blur', () async { + if (impellerEnabled) { + print('Disabled - see https://github.com/flutter/flutter/issues/135712'); + return; + } final Paint paint = Paint() ..color = green ..imageFilter = makeBlur(1.0, 1.0, TileMode.decal); @@ -201,6 +207,11 @@ void main() { }); test('ImageFilter - matrix', () async { + if (impellerEnabled) { + print('Disabled - see https://github.com/flutter/flutter/issues/135712'); + return; + } + final Paint paint = Paint() ..color = green ..imageFilter = makeScale(2.0, 2.0, 1.5, 1.5); @@ -227,6 +238,11 @@ void main() { }); test('ImageFilter - from color filters', () async { + if (impellerEnabled) { + print('Disabled - see https://github.com/flutter/flutter/issues/135712'); + return; + } + final Paint paint = Paint() ..color = green ..imageFilter = const ColorFilter.matrix(constValueColorMatrix); @@ -236,6 +252,11 @@ void main() { }); test('ImageFilter - color filter composition', () async { + if (impellerEnabled) { + print('Disabled - see https://github.com/flutter/flutter/issues/135712'); + return; + } + final ImageFilter compOrder1 = ImageFilter.compose( outer: const ColorFilter.matrix(halvesBrightnessColorMatrix), inner: const ColorFilter.matrix(constValueColorMatrix), diff --git a/testing/dart/impeller_enabled.dart b/testing/dart/impeller_enabled.dart new file mode 100644 index 0000000000000..18c457e3c059f --- /dev/null +++ b/testing/dart/impeller_enabled.dart @@ -0,0 +1,7 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:io'; + +bool get impellerEnabled => Platform.executableArguments.contains('--enable-impeller'); diff --git a/testing/dart/observatory/skp_test.dart b/testing/dart/observatory/skp_test.dart index 239e3b529f27a..6c2a1460f9f21 100644 --- a/testing/dart/observatory/skp_test.dart +++ b/testing/dart/observatory/skp_test.dart @@ -12,6 +12,8 @@ import 'package:litetest/litetest.dart'; import 'package:vm_service/vm_service.dart' as vms; import 'package:vm_service/vm_service_io.dart'; +import '../impeller_enabled.dart'; + void main() { test('Capture an SKP ', () async { final developer.ServiceProtocolInfo info = await developer.Service.getInfo(); @@ -42,13 +44,19 @@ void main() { PlatformDispatcher.instance.scheduleFrame(); await completer.future; - final vms.Response response = await vmService.callServiceExtension('_flutter.screenshotSkp'); + try { + final vms.Response response = await vmService.callServiceExtension('_flutter.screenshotSkp'); + expect(impellerEnabled, false); + final String base64data = response.json!['skp'] as String; + expect(base64data, isNotNull); + expect(base64data, isNotEmpty); + final Uint8List decoded = base64Decode(base64data); + expect(decoded.sublist(0, 8), 'skiapict'.codeUnits); + } on vms.RPCError catch (e) { + expect(impellerEnabled, true); + expect(e.toString(), contains('Cannot capture SKP screenshot with Impeller enabled.')); + } - final String base64data = response.json!['skp'] as String; - expect(base64data, isNotNull); - expect(base64data, isNotEmpty); - final Uint8List decoded = base64Decode(base64data); - expect(decoded.sublist(0, 8), 'skiapict'.codeUnits); await vmService.dispose(); }); diff --git a/testing/dart/observatory/tracing_test.dart b/testing/dart/observatory/tracing_test.dart index 1937c9b11df1e..6372a6a159763 100644 --- a/testing/dart/observatory/tracing_test.dart +++ b/testing/dart/observatory/tracing_test.dart @@ -12,6 +12,8 @@ import 'package:vm_service/vm_service.dart' as vms; import 'package:vm_service/vm_service_io.dart'; import 'package:vm_service_protos/vm_service_protos.dart'; +import '../impeller_enabled.dart'; + Future _testChromeFormatTrace(vms.VmService vmService) async { final vms.Timeline timeline = await vmService.getVMTimeline(); @@ -32,7 +34,7 @@ Future _testChromeFormatTrace(vms.VmService vmService) async { } } expect(saveLayerRecordCount, 3); - expect(saveLayerCount, 3); + expect(saveLayerCount, impellerEnabled ? 2 : 3); expect(flowEventCount, 5); } @@ -59,7 +61,7 @@ Future _testPerfettoFormatTrace(vms.VmService vmService) async { } } expect(saveLayerRecordCount, 3); - expect(saveLayerCount, 3); + expect(saveLayerCount, impellerEnabled ? 2 : 3); expect(flowIdCount, 5); } @@ -80,6 +82,7 @@ void main() { final PictureRecorder recorder = PictureRecorder(); final Canvas canvas = Canvas(recorder); canvas.drawColor(const Color(0xff0000ff), BlendMode.srcOut); + // Will saveLayer implicitly for Skia, but not Impeller. canvas.drawPaint(Paint()..imageFilter = ImageFilter.blur(sigmaX: 2, sigmaY: 3)); canvas.saveLayer(null, Paint()); canvas.drawRect(const Rect.fromLTRB(10, 10, 20, 20), Paint()); diff --git a/testing/dart/observatory/vmservice_methods_test.dart b/testing/dart/observatory/vmservice_methods_test.dart index fa522b751ed09..14fd20d2afcb1 100644 --- a/testing/dart/observatory/vmservice_methods_test.dart +++ b/testing/dart/observatory/vmservice_methods_test.dart @@ -12,6 +12,8 @@ import 'package:litetest/litetest.dart'; import 'package:vm_service/vm_service.dart' as vms; import 'package:vm_service/vm_service_io.dart'; +import '../impeller_enabled.dart'; + void main() { test('Setting invalid directory returns an error', () async { vms.VmService? vmService; @@ -59,7 +61,7 @@ void main() { 'ext.ui.window.impellerEnabled', isolateId: isolateId, ); - expect(response.json!['enabled'], false); + expect(response.json!['enabled'], impellerEnabled); } finally { await vmService?.dispose(); } diff --git a/testing/run_tests.py b/testing/run_tests.py index 898201cecf5bd..500dbba643d03 100755 --- a/testing/run_tests.py +++ b/testing/run_tests.py @@ -576,13 +576,37 @@ def run_engine_benchmarks(build_dir, executable_filter): ) -def gather_dart_test( - build_dir, - dart_file, - multithreaded, - enable_observatory=False, - expect_failure=False, -): +class FlutterTesterOptions(): + + def __init__( + self, + multithreaded=False, + enable_impeller=False, + enable_observatory=False, + expect_failure=False + ): + self.multithreaded = multithreaded + self.enable_impeller = enable_impeller + self.enable_observatory = enable_observatory + self.expect_failure = expect_failure + + def apply_args(self, command_args): + if not self.enable_observatory: + command_args.append('--disable-observatory') + + if self.enable_impeller: + command_args += ['--enable-impeller'] + + if self.multithreaded: + command_args.insert(0, '--force-multithreading') + + def threading_description(self): + if self.multithreaded: + return 'multithreaded' + return 'single-threaded' + + +def gather_dart_test(build_dir, dart_file, options): kernel_file_name = os.path.basename(dart_file) + '.dill' kernel_file_output = os.path.join(build_dir, 'gen', kernel_file_name) error_message = "%s doesn't exist. Please run the build that populates %s" % ( @@ -591,8 +615,8 @@ def gather_dart_test( assert os.path.isfile(kernel_file_output), error_message command_args = [] - if not enable_observatory: - command_args.append('--disable-observatory') + + options.apply_args(command_args) dart_file_contents = open(dart_file, 'r') custom_options = re.findall( @@ -610,18 +634,12 @@ def gather_dart_test( kernel_file_output, ] - if multithreaded: - threading = 'multithreaded' - command_args.insert(0, '--force-multithreading') - else: - threading = 'single-threaded' - tester_name = 'flutter_tester' logger.info( "Running test '%s' using '%s' (%s)", kernel_file_name, tester_name, - threading + options.threading_description() ) - forbidden_output = [] if 'unopt' in build_dir or expect_failure else [ + forbidden_output = [] if 'unopt' in build_dir or options.expect_failure else [ '[ERROR' ] return EngineExecutableTask( @@ -630,7 +648,7 @@ def gather_dart_test( None, command_args, forbidden_output=forbidden_output, - expect_failure=expect_failure, + expect_failure=options.expect_failure, ) @@ -849,8 +867,38 @@ def gather_dart_tests(build_dir, test_filter): logger.info( "Gathering dart test '%s' with observatory enabled", dart_test_file ) - yield gather_dart_test(build_dir, dart_test_file, True, True) - yield gather_dart_test(build_dir, dart_test_file, False, True) + yield gather_dart_test( + build_dir, dart_test_file, + FlutterTesterOptions( + multithreaded=True, + enable_impeller=False, + enable_observatory=True + ) + ) + yield gather_dart_test( + build_dir, dart_test_file, + FlutterTesterOptions( + multithreaded=True, + enable_impeller=True, + enable_observatory=True + ) + ) + yield gather_dart_test( + build_dir, dart_test_file, + FlutterTesterOptions( + multithreaded=False, + enable_impeller=False, + enable_observatory=True + ) + ) + yield gather_dart_test( + build_dir, dart_test_file, + FlutterTesterOptions( + multithreaded=False, + enable_impeller=True, + enable_observatory=True + ) + ) for dart_test_file in dart_tests: if test_filter is not None and os.path.basename(dart_test_file @@ -858,8 +906,22 @@ def gather_dart_tests(build_dir, test_filter): logger.info("Skipping '%s' due to filter.", dart_test_file) else: logger.info("Gathering dart test '%s'", dart_test_file) - yield gather_dart_test(build_dir, dart_test_file, True) - yield gather_dart_test(build_dir, dart_test_file, False) + yield gather_dart_test( + build_dir, dart_test_file, + FlutterTesterOptions(multithreaded=True, enable_impeller=False) + ) + yield gather_dart_test( + build_dir, dart_test_file, + FlutterTesterOptions(multithreaded=True, enable_impeller=True) + ) + yield gather_dart_test( + build_dir, dart_test_file, + FlutterTesterOptions(multithreaded=False, enable_impeller=False) + ) + yield gather_dart_test( + build_dir, dart_test_file, + FlutterTesterOptions(multithreaded=False, enable_impeller=True) + ) def gather_dart_smoke_test(build_dir, test_filter): @@ -874,8 +936,14 @@ def gather_dart_smoke_test(build_dir, test_filter): ) not in test_filter: logger.info("Skipping '%s' due to filter.", smoke_test) else: - yield gather_dart_test(build_dir, smoke_test, True, expect_failure=True) - yield gather_dart_test(build_dir, smoke_test, False, expect_failure=True) + yield gather_dart_test( + build_dir, smoke_test, + FlutterTesterOptions(multithreaded=True, expect_failure=True) + ) + yield gather_dart_test( + build_dir, smoke_test, + FlutterTesterOptions(multithreaded=False, expect_failure=True) + ) def gather_dart_package_tests(build_dir, package_path, extra_opts): diff --git a/testing/test_vulkan_context.cc b/testing/test_vulkan_context.cc index ea36581add8e2..5652431a800ad 100644 --- a/testing/test_vulkan_context.cc +++ b/testing/test_vulkan_context.cc @@ -14,19 +14,12 @@ #include "flutter/fml/memory/ref_ptr.h" #include "flutter/fml/native_library.h" +#include "flutter/vulkan/swiftshader_path.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/gpu/GrDirectContext.h" #include "third_party/skia/include/gpu/vk/GrVkExtensions.h" #include "vulkan/vulkan_core.h" -#ifdef FML_OS_MACOSX -#define VULKAN_SO_PATH "libvk_swiftshader.dylib" -#elif FML_OS_WIN -#define VULKAN_SO_PATH "vk_swiftshader.dll" -#else -#define VULKAN_SO_PATH "libvk_swiftshader.so" -#endif - namespace flutter { namespace testing { diff --git a/vulkan/swiftshader_path.h b/vulkan/swiftshader_path.h new file mode 100644 index 0000000000000..424116a7efec7 --- /dev/null +++ b/vulkan/swiftshader_path.h @@ -0,0 +1,18 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_VULKAN_SWIFTSHADER_PATH_H_ +#define FLUTTER_VULKAN_SWIFTSHADER_PATH_H_ + +#ifndef VULKAN_SO_PATH +#if FML_OS_MACOSX +#define VULKAN_SO_PATH "libvk_swiftshader.dylib" +#elif FML_OS_WIN +#define VULKAN_SO_PATH "vk_swiftshader.dll" +#else +#define VULKAN_SO_PATH "libvk_swiftshader.so" +#endif // !FML_OS_MACOSX && !FML_OS_WIN +#endif // VULKAN_SO_PATH + +#endif // FLUTTER_VULKAN_SWIFTSHADER_PATH_H_ diff --git a/vulkan/vulkan_window.cc b/vulkan/vulkan_window.cc index f7f51dce9e738..345919b83d8c1 100644 --- a/vulkan/vulkan_window.cc +++ b/vulkan/vulkan_window.cc @@ -118,6 +118,7 @@ GrDirectContext* VulkanWindow::GetSkiaGrContext() { } bool VulkanWindow::CreateSkiaGrContext() { +#ifdef SK_VUKLAN GrVkBackendContext backend_context; if (!CreateSkiaBackendContext(&backend_context)) { @@ -138,6 +139,9 @@ bool VulkanWindow::CreateSkiaGrContext() { skia_gr_context_ = context; return true; +#else + return false; +#endif // SK_VULKAN } bool VulkanWindow::CreateSkiaBackendContext(GrVkBackendContext* context) {