[Impeller] flutter_tester --enable-impeller (#46389)
This patch does the following:
- Updates `flutter_tester` to set up an Impeller rendering context and surface if `--enable-impeller` is set to true, using the Vulkan backend with Swiftshader.
- Updates `run_tests.py` to run all tests except the smoke test (that one really has no rendering impact whatsoever) with and without `--enable-impeller`.
- Updates a few tests to work that were trivial:
- A couple tests needed updated goldens for very minor rendering differences. Filed https://github.com/flutter/flutter/issues/135684 to track using Skia gold for this instead.
- Disabled SKP screenshotting if Impeller is enabled, and updated the test checking that to verify an error is thrown if an SKP is requested.
- The Dart GPU based test now asserts that the gpu context is available if Impeller is enabled, and does not deadlock if run in a single threaded mode.
- We were missing some trace events around `Canvas::SaveLayer` for Impeller as compared to Skia.
- A couple other tests had strict checks about exception messages that are slightly different between Skia and Impeller.
- I've filed bugs for other tests that may require a little more work, and skipped them for now. For FragmentProgram on Vulkan I reused an existing bug.
This is part of my attempt to address https://github.com/flutter/flutter/issues/135693, although @chinmaygarde and I had slightly different ideas about how to do this.
The goals here are:
- Run the Dart unit tests we already have with Impeller enabled.
- Enable running more of the framework tests (including gold tests) with Impeller enabled.
- Run all of these tests via public `dart:ui` API rather than mucking around in C++ internals in the engine.
diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter
index 92979f5..589e361 100644
--- a/ci/licenses_golden/licenses_flutter
+++ b/ci/licenses_golden/licenses_flutter
@@ -4043,6 +4043,7 @@
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
@@ -6828,6 +6829,7 @@
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 696226f..c02ccd0 100644
--- a/impeller/BUILD.gn
+++ b/impeller/BUILD.gn
@@ -34,6 +34,10 @@
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 d4d3829..2308d53 100644
--- a/impeller/aiks/canvas.cc
+++ b/impeller/aiks/canvas.cc
@@ -8,6 +8,7 @@
#include <utility>
#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 @@
void Canvas::SaveLayer(const Paint& paint,
std::optional<Rect> bounds,
const std::shared_ptr<ImageFilter>& 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 bb41c50..bbfd7ef 100644
--- a/impeller/base/validation.cc
+++ b/impeller/base/validation.cc
@@ -48,7 +48,7 @@
} 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 93eb4eb..8d2f591 100644
--- a/impeller/playground/playground.cc
+++ b/impeller/playground/playground.cc
@@ -102,7 +102,7 @@
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 3fc4f2f..f90ee4b 100644
--- a/impeller/renderer/backend/vulkan/allocator_vk.cc
+++ b/impeller/renderer/backend/vulkan/allocator_vk.cc
@@ -265,6 +265,7 @@
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 9b911c6..260c9e4 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 @@
auto encoder = std::make_unique<CommandEncoderFactoryVK>(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 @@
auto encoder = std::make_unique<CommandEncoderFactoryVK>(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 @@
auto encoder = std::make_unique<CommandEncoderFactoryVK>(context)->Create();
BlitCopyBufferToTextureCommandVK cmd;
cmd.destination = context->GetResourceAllocator()->CreateTexture({
+ .format = PixelFormat::kR8G8B8A8UNormInt,
.size = ISize(100, 100),
});
cmd.source = context->GetResourceAllocator()
@@ -66,6 +70,7 @@
auto encoder = std::make_unique<CommandEncoderFactoryVK>(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 2e20d2a..afc1407 100644
--- a/impeller/renderer/backend/vulkan/surface_context_vk.cc
+++ b/impeller/renderer/backend/vulkan/surface_context_vk.cc
@@ -63,6 +63,10 @@
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 0af8800..dcd5d1c 100644
--- a/impeller/renderer/backend/vulkan/swapchain_impl_vk.cc
+++ b/impeller/renderer/backend/vulkan/swapchain_impl_vk.cc
@@ -142,6 +142,7 @@
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 0a09a9e..c5399ce 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 @@
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<SwapchainVK>(new SwapchainVK(std::move(impl)));
diff --git a/impeller/tools/impeller.gni b/impeller/tools/impeller.gni
index 35758f3..15caa56 100644
--- a/impeller/tools/impeller.gni
+++ b/impeller/tools/impeller.gni
@@ -22,7 +22,14 @@
(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 3441832..7539f0c 100644
--- a/lib/gpu/context.cc
+++ b/lib/gpu/context.cc
@@ -55,7 +55,8 @@
// Grab the Impeller context from the IO manager.
std::promise<std::shared_ptr<impeller::Context>> 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 0000000..bdec9bc
--- /dev/null
+++ b/lib/ui/fixtures/impeller_2_dispose_op_restore_previous.apng.67.png
Binary files 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 0000000..6ade80e
--- /dev/null
+++ b/lib/ui/fixtures/impeller_2_dispose_op_restore_previous.apng.68.png
Binary files 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 0000000..c3006d0
--- /dev/null
+++ b/lib/ui/fixtures/impeller_2_dispose_op_restore_previous.apng.69.png
Binary files 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 0000000..7c67236
--- /dev/null
+++ b/lib/ui/fixtures/impeller_four_frame_with_reuse_end.png
Binary files differ
diff --git a/lib/ui/fixtures/impeller_heart_end.png b/lib/ui/fixtures/impeller_heart_end.png
new file mode 100644
index 0000000..cd33ff0
--- /dev/null
+++ b/lib/ui/fixtures/impeller_heart_end.png
Binary files differ
diff --git a/shell/common/shell.cc b/shell/common/shell.cc
index fc00630..a6ba487 100644
--- a/shell/common/shell.cc
+++ b/shell/common/shell.cc
@@ -1695,6 +1695,11 @@
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 3817011..d19e5cb 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 a8976d6..63f1359 100644
--- a/shell/gpu/gpu_surface_vulkan.cc
+++ b/shell/gpu/gpu_surface_vulkan.cc
@@ -104,6 +104,7 @@
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 @@
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 3b6ec9d..917b5f0 100644
--- a/shell/gpu/gpu_surface_vulkan_impeller.cc
+++ b/shell/gpu/gpu_surface_vulkan_impeller.cc
@@ -60,6 +60,11 @@
auto& context_vk = impeller::SurfaceContextVK::Cast(*impeller_context_);
std::unique_ptr<impeller::Surface> 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 ec6400c..8f45723 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 @@
]
sources = [ "tester_main.cc" ]
+ libs = []
if (is_win) {
- libs = [
+ libs += [
"psapi.lib",
"user32.lib",
"FontSub.lib",
@@ -36,6 +46,14 @@
"//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 310ce62..9c0059b 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 <vulkan/vulkan.h> // 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<std::shared_ptr<fml::Mapping>> ShaderLibraryMappings() {
+ return {
+ std::make_shared<fml::NonOwnedMapping>(impeller_entity_shaders_vk_data,
+ impeller_entity_shaders_vk_length),
+ std::make_shared<fml::NonOwnedMapping>(
+ impeller_modern_shaders_vk_data, impeller_modern_shaders_vk_length),
+#if IMPELLER_ENABLE_3D
+ std::make_shared<fml::NonOwnedMapping>(
+ impeller_scene_shaders_vk_data, impeller_scene_shaders_vk_length),
+#endif // IMPELLER_ENABLE_3D
+ std::make_shared<fml::NonOwnedMapping>(
+ impeller_compute_shaders_vk_data,
+ impeller_compute_shaders_vk_length),
+ };
+}
+
+struct ImpellerVulkanContextHolder {
+ fml::RefPtr<vulkan::VulkanProcTable> vulkan_proc_table;
+ std::shared_ptr<impeller::ContextVK> context;
+ std::shared_ptr<impeller::SurfaceContextVK> surface_context;
+};
+#else
+struct ImpellerVulkanContextHolder {};
+#endif // IMPELLER_SUPPORTS_RENDERING
+
#if defined(FML_OS_WIN)
#include <combaseapi.h>
#endif // defined(FML_OS_WIN)
@@ -81,11 +121,41 @@
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<impeller::Context> GetImpellerContext() const override {
+#if IMPELLER_SUPPORTS_RENDERING
+ return std::static_pointer_cast<impeller::Context>(
+ impeller_context_holder_.context);
+#else
+ return nullptr;
+#endif // IMPELLER_SUPPORTS_RENDERING
+ }
// |PlatformView|
std::unique_ptr<Surface> CreateRenderingSurface() override {
+#if IMPELLER_SUPPORTS_RENDERING
+ if (delegate_.OnPlatformViewGetSettings().enable_impeller) {
+ FML_DCHECK(impeller_context_holder_.context);
+ auto surface = std::make_unique<GPUSurfaceVulkanImpeller>(
+ impeller_context_holder_.surface_context);
+ FML_DCHECK(surface->IsValid());
+ return surface;
+ }
+#endif // IMPELLER_SUPPORTS_RENDERING
auto surface = std::make_unique<TesterGPUSurfaceSoftware>(
this, true /* render to surface */);
FML_DCHECK(surface->IsValid());
@@ -126,6 +196,7 @@
private:
sk_sp<SkSurface> sk_surface_ = nullptr;
+ [[maybe_unused]] ImpellerVulkanContextHolder impeller_context_holder_;
std::shared_ptr<TesterExternalViewEmbedder> external_view_embedder_ =
std::make_shared<TesterExternalViewEmbedder>();
};
@@ -235,10 +306,63 @@
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::VulkanProcTable>(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<PlatformView> on_create_platform_view =
- [](Shell& shell) {
- return std::make_unique<TesterPlatformView>(shell,
- shell.GetTaskRunners());
+ [impeller_context_holder =
+ std::move(impeller_context_holder)](Shell& shell) {
+ return std::make_unique<TesterPlatformView>(
+ shell, shell.GetTaskRunners(), impeller_context_holder);
};
Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
diff --git a/testing/dart/canvas_test.dart b/testing/dart/canvas_test.dart
index 6732423..d317e2f 100644
--- a/testing/dart/canvas_test.dart
+++ b/testing/dart/canvas_test.dart
@@ -12,6 +12,8 @@
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<Image> createImage(int width, int height) {
@@ -192,7 +194,7 @@
final bool areEqual =
await fuzzyGoldenImageCompare(image, 'canvas_test_toImage.png');
expect(areEqual, true);
- });
+ }, skip: impellerEnabled);
Gradient makeGradient() {
return Gradient.linear(
@@ -213,7 +215,7 @@
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 @@
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 @@
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 @@
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 fb07a63..702a5fd 100644
--- a/testing/dart/codec_test.dart
+++ b/testing/dart/codec_test.dart
@@ -9,6 +9,8 @@
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 @@
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 @@
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 @@
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 @@
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 e555360..66ec954 100644
--- a/testing/dart/color_filter_test.dart
+++ b/testing/dart/color_filter_test.dart
@@ -7,6 +7,8 @@
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 @@
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 @@
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 @@
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 @@
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 9ca46b9..2aa426a 100644
--- a/testing/dart/encoding_test.dart
+++ b/testing/dart/encoding_test.dart
@@ -10,6 +10,8 @@
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 @@
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 @@
});
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 @@
});
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<int> expected = await readFile('square.png');
diff --git a/testing/dart/fragment_shader_test.dart b/testing/dart/fragment_shader_test.dart
index e97eb51..da34695 100644
--- a/testing/dart/fragment_shader_test.dart
+++ b/testing/dart/fragment_shader_test.dart
@@ -12,6 +12,7 @@
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
});
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 @@
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<String, FragmentProgram> 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 0c96b66..9d65c8e 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 @@
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 0fa8651..0a79513 100644
--- a/testing/dart/image_filter_test.dart
+++ b/testing/dart/image_filter_test.dart
@@ -7,6 +7,8 @@
import 'package:litetest/litetest.dart';
+import 'impeller_enabled.dart';
+
const Color red = Color(0xFFAA0000);
const Color green = Color(0xFF00AA00);
@@ -174,6 +176,10 @@
}
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 @@
});
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 @@
});
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 @@
});
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 0000000..18c457e
--- /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 239e3b5..6c2a146 100644
--- a/testing/dart/observatory/skp_test.dart
+++ b/testing/dart/observatory/skp_test.dart
@@ -12,6 +12,8 @@
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 @@
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 1937c9b..6372a6a 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_io.dart';
import 'package:vm_service_protos/vm_service_protos.dart';
+import '../impeller_enabled.dart';
+
Future<void> _testChromeFormatTrace(vms.VmService vmService) async {
final vms.Timeline timeline = await vmService.getVMTimeline();
@@ -32,7 +34,7 @@
}
}
expect(saveLayerRecordCount, 3);
- expect(saveLayerCount, 3);
+ expect(saveLayerCount, impellerEnabled ? 2 : 3);
expect(flowEventCount, 5);
}
@@ -59,7 +61,7 @@
}
}
expect(saveLayerRecordCount, 3);
- expect(saveLayerCount, 3);
+ expect(saveLayerCount, impellerEnabled ? 2 : 3);
expect(flowIdCount, 5);
}
@@ -80,6 +82,7 @@
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 fa522b7..14fd20d 100644
--- a/testing/dart/observatory/vmservice_methods_test.dart
+++ b/testing/dart/observatory/vmservice_methods_test.dart
@@ -12,6 +12,8 @@
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 @@
'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 898201c..500dbba 100755
--- a/testing/run_tests.py
+++ b/testing/run_tests.py
@@ -576,13 +576,37 @@
)
-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 @@
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 @@
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 @@
None,
command_args,
forbidden_output=forbidden_output,
- expect_failure=expect_failure,
+ expect_failure=options.expect_failure,
)
@@ -849,8 +867,38 @@
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 @@
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 @@
) 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 ea36581..5652431 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 0000000..424116a
--- /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 f7f51dc..345919b 100644
--- a/vulkan/vulkan_window.cc
+++ b/vulkan/vulkan_window.cc
@@ -118,6 +118,7 @@
}
bool VulkanWindow::CreateSkiaGrContext() {
+#ifdef SK_VUKLAN
GrVkBackendContext backend_context;
if (!CreateSkiaBackendContext(&backend_context)) {
@@ -138,6 +139,9 @@
skia_gr_context_ = context;
return true;
+#else
+ return false;
+#endif // SK_VULKAN
}
bool VulkanWindow::CreateSkiaBackendContext(GrVkBackendContext* context) {