diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index 41ade31557..e4b8b44cad 100644 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -5317,6 +5317,10 @@ ORIGIN: ../../../flutter/impeller/golden_tests/metal_screenshot.h + ../../../flu ORIGIN: ../../../flutter/impeller/golden_tests/metal_screenshot.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/golden_tests/metal_screenshotter.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/golden_tests/metal_screenshotter.mm + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/golden_tests/screenshot.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/golden_tests/screenshotter.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/golden_tests/vulkan_screenshotter.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/golden_tests/vulkan_screenshotter.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/golden_tests/working_directory.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/golden_tests/working_directory.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/golden_tests_harvester/bin/golden_tests_harvester.dart + ../../../flutter/LICENSE @@ -8155,6 +8159,10 @@ FILE: ../../../flutter/impeller/golden_tests/metal_screenshot.h FILE: ../../../flutter/impeller/golden_tests/metal_screenshot.mm FILE: ../../../flutter/impeller/golden_tests/metal_screenshotter.h FILE: ../../../flutter/impeller/golden_tests/metal_screenshotter.mm +FILE: ../../../flutter/impeller/golden_tests/screenshot.h +FILE: ../../../flutter/impeller/golden_tests/screenshotter.h +FILE: ../../../flutter/impeller/golden_tests/vulkan_screenshotter.h +FILE: ../../../flutter/impeller/golden_tests/vulkan_screenshotter.mm FILE: ../../../flutter/impeller/golden_tests/working_directory.cc FILE: ../../../flutter/impeller/golden_tests/working_directory.h FILE: ../../../flutter/impeller/golden_tests_harvester/bin/golden_tests_harvester.dart diff --git a/engine/src/flutter/display_list/testing/dl_test_surface_metal.cc b/engine/src/flutter/display_list/testing/dl_test_surface_metal.cc index 2cce8f4e5e..b7d7f7047b 100644 --- a/engine/src/flutter/display_list/testing/dl_test_surface_metal.cc +++ b/engine/src/flutter/display_list/testing/dl_test_surface_metal.cc @@ -58,10 +58,9 @@ std::shared_ptr DlMetalSurfaceProvider::MakeOffscreenSurface( } class DlMetalPixelData : public DlPixelData { - using MetalScreenshot = impeller::testing::MetalScreenshot; - public: - explicit DlMetalPixelData(std::unique_ptr screenshot) + explicit DlMetalPixelData( + std::unique_ptr screenshot) : screenshot_(std::move(screenshot)), addr_(reinterpret_cast(screenshot_->GetBytes())), ints_per_row_(screenshot_->GetBytesPerRow() / 4) { @@ -79,7 +78,7 @@ class DlMetalPixelData : public DlPixelData { } private: - std::unique_ptr screenshot_; + std::unique_ptr screenshot_; const uint32_t* addr_; const uint32_t ints_per_row_; }; diff --git a/engine/src/flutter/impeller/aiks/aiks_unittests.cc b/engine/src/flutter/impeller/aiks/aiks_unittests.cc index 6d92b8585a..6df57455ee 100644 --- a/engine/src/flutter/impeller/aiks/aiks_unittests.cc +++ b/engine/src/flutter/impeller/aiks/aiks_unittests.cc @@ -3816,6 +3816,8 @@ TEST_P(AiksTest, GaussianBlurMipMapNestedLayer) { std::max(it->texture->GetTextureDescriptor().mip_count, max_mip_count); } EXPECT_EQ(max_mip_count, blur_required_mip_count); + // The log is FML_DLOG, so only check in debug builds. +#ifndef NDEBUG if (GetParam() == PlaygroundBackend::kMetal) { EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError), std::string::npos); @@ -3823,6 +3825,7 @@ TEST_P(AiksTest, GaussianBlurMipMapNestedLayer) { EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError), std::string::npos); } +#endif } TEST_P(AiksTest, GaussianBlurMipMapImageFilter) { @@ -3849,6 +3852,8 @@ TEST_P(AiksTest, GaussianBlurMipMapImageFilter) { std::max(it->texture->GetTextureDescriptor().mip_count, max_mip_count); } EXPECT_EQ(max_mip_count, blur_required_mip_count); + // The log is FML_DLOG, so only check in debug builds. +#ifndef NDEBUG if (GetParam() == PlaygroundBackend::kMetal) { EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError), std::string::npos); @@ -3856,6 +3861,7 @@ TEST_P(AiksTest, GaussianBlurMipMapImageFilter) { EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError), std::string::npos); } +#endif } } // namespace testing diff --git a/engine/src/flutter/impeller/golden_tests/BUILD.gn b/engine/src/flutter/impeller/golden_tests/BUILD.gn index 5b679c6a7e..d17a59e03f 100644 --- a/engine/src/flutter/impeller/golden_tests/BUILD.gn +++ b/engine/src/flutter/impeller/golden_tests/BUILD.gn @@ -49,6 +49,10 @@ if (is_mac) { "metal_screenshot.mm", "metal_screenshotter.h", "metal_screenshotter.mm", + "screenshot.h", + "screenshotter.h", + "vulkan_screenshotter.h", + "vulkan_screenshotter.mm", ] deps = [ @@ -56,6 +60,7 @@ if (is_mac) { "//flutter/impeller/display_list", "//flutter/impeller/playground", "//flutter/impeller/renderer/backend/metal:metal", + "//flutter/impeller/renderer/backend/vulkan", ] } diff --git a/engine/src/flutter/impeller/golden_tests/golden_playground_test_mac.cc b/engine/src/flutter/impeller/golden_tests/golden_playground_test_mac.cc index 18ca8c4a9a..bbd544a566 100644 --- a/engine/src/flutter/impeller/golden_tests/golden_playground_test_mac.cc +++ b/engine/src/flutter/impeller/golden_tests/golden_playground_test_mac.cc @@ -11,6 +11,7 @@ #include "flutter/impeller/aiks/picture.h" #include "flutter/impeller/golden_tests/golden_digest.h" #include "flutter/impeller/golden_tests/metal_screenshotter.h" +#include "flutter/impeller/golden_tests/vulkan_screenshotter.h" #include "impeller/typographer/backends/skia/typographer_context_skia.h" #include "impeller/typographer/typographer_context.h" @@ -57,6 +58,9 @@ static const std::vector kSkipTests = { "impeller_Play_AiksTest_CanRenderClippedRuntimeEffects_Vulkan", "impeller_Play_AiksTest_CaptureContext_Metal", "impeller_Play_AiksTest_CaptureContext_Vulkan", + // TODO(https://github.com/flutter/flutter/issues/141891): This tests + // crashes on vulkan and needs to be fixed. + "impeller_Play_AiksTest_DrawPaintTransformsBounds_Vulkan", }; namespace { @@ -77,7 +81,7 @@ std::string GetGoldenFilename() { return GetTestName() + ".png"; } -bool SaveScreenshot(std::unique_ptr screenshot) { +bool SaveScreenshot(std::unique_ptr screenshot) { if (!screenshot || !screenshot->GetBytes()) { return false; } @@ -91,15 +95,19 @@ bool SaveScreenshot(std::unique_ptr screenshot) { } // namespace struct GoldenPlaygroundTest::GoldenPlaygroundTestImpl { - GoldenPlaygroundTestImpl() - : screenshotter(new testing::MetalScreenshotter()) {} - std::unique_ptr screenshotter; + std::unique_ptr screenshotter; ISize window_size = ISize{1024, 768}; }; GoldenPlaygroundTest::GoldenPlaygroundTest() : typographer_context_(TypographerContextSkia::Make()), - pimpl_(new GoldenPlaygroundTest::GoldenPlaygroundTestImpl()) {} + pimpl_(new GoldenPlaygroundTest::GoldenPlaygroundTestImpl()) { + if (GetParam() == PlaygroundBackend::kMetal) { + pimpl_->screenshotter = std::make_unique(); + } else if (GetParam() == PlaygroundBackend::kVulkan) { + pimpl_->screenshotter = std::make_unique(); + } +} GoldenPlaygroundTest::~GoldenPlaygroundTest() = default; @@ -122,7 +130,8 @@ void GoldenPlaygroundTest::SetUp() { std::filesystem::path icd_path = target_path / "vk_swiftshader_icd.json"; setenv("VK_ICD_FILENAMES", icd_path.c_str(), 1); - if (GetBackend() != PlaygroundBackend::kMetal) { + if (GetBackend() != PlaygroundBackend::kMetal && + GetBackend() != PlaygroundBackend::kVulkan) { GTEST_SKIP_("GoldenPlaygroundTest doesn't support this backend type."); return; } @@ -157,7 +166,7 @@ bool GoldenPlaygroundTest::OpenPlaygroundHere( AiksContext renderer(GetContext(), typographer_context_); std::optional picture; - std::unique_ptr screenshot; + std::unique_ptr screenshot; for (int i = 0; i < 2; ++i) { picture = callback(renderer); if (!picture.has_value()) { diff --git a/engine/src/flutter/impeller/golden_tests/golden_tests.cc b/engine/src/flutter/impeller/golden_tests/golden_tests.cc index 84b6c6fcda..c519f367a1 100644 --- a/engine/src/flutter/impeller/golden_tests/golden_tests.cc +++ b/engine/src/flutter/impeller/golden_tests/golden_tests.cc @@ -34,7 +34,7 @@ std::string GetGoldenFilename() { return GetTestName() + ".png"; } -bool SaveScreenshot(std::unique_ptr screenshot) { +bool SaveScreenshot(std::unique_ptr screenshot) { if (!screenshot || !screenshot->GetBytes()) { return false; } diff --git a/engine/src/flutter/impeller/golden_tests/metal_screenshot.h b/engine/src/flutter/impeller/golden_tests/metal_screenshot.h index d2f9dab09b..dc3ebf697c 100644 --- a/engine/src/flutter/impeller/golden_tests/metal_screenshot.h +++ b/engine/src/flutter/impeller/golden_tests/metal_screenshot.h @@ -5,6 +5,8 @@ #ifndef FLUTTER_IMPELLER_GOLDEN_TESTS_METAL_SCREENSHOT_H_ #define FLUTTER_IMPELLER_GOLDEN_TESTS_METAL_SCREENSHOT_H_ +#include "flutter/impeller/golden_tests/screenshot.h" + #include #include #include @@ -15,23 +17,23 @@ namespace impeller { namespace testing { /// A screenshot that was produced from `MetalScreenshotter`. -class MetalScreenshot { +class MetalScreenshot : public Screenshot { public: + explicit MetalScreenshot(CGImageRef cgImage); + ~MetalScreenshot(); - const UInt8* GetBytes() const; + const uint8_t* GetBytes() const override; - size_t GetHeight() const; + size_t GetHeight() const override; - size_t GetWidth() const; + size_t GetWidth() const override; - size_t GetBytesPerRow() const; + size_t GetBytesPerRow() const override; - bool WriteToPNG(const std::string& path) const; + bool WriteToPNG(const std::string& path) const override; private: - friend class MetalScreenshotter; - explicit MetalScreenshot(CGImageRef cgImage); MetalScreenshot(const MetalScreenshot&) = delete; MetalScreenshot& operator=(const MetalScreenshot&) = delete; diff --git a/engine/src/flutter/impeller/golden_tests/metal_screenshot.mm b/engine/src/flutter/impeller/golden_tests/metal_screenshot.mm index 767ee93cb4..fd7ab0c083 100644 --- a/engine/src/flutter/impeller/golden_tests/metal_screenshot.mm +++ b/engine/src/flutter/impeller/golden_tests/metal_screenshot.mm @@ -17,7 +17,7 @@ MetalScreenshot::~MetalScreenshot() { CGImageRelease(cg_image_); } -const UInt8* MetalScreenshot::GetBytes() const { +const uint8_t* MetalScreenshot::GetBytes() const { return CFDataGetBytePtr(pixel_data_); } diff --git a/engine/src/flutter/impeller/golden_tests/metal_screenshotter.h b/engine/src/flutter/impeller/golden_tests/metal_screenshotter.h index 4d994cb27f..582462a73f 100644 --- a/engine/src/flutter/impeller/golden_tests/metal_screenshotter.h +++ b/engine/src/flutter/impeller/golden_tests/metal_screenshotter.h @@ -8,6 +8,7 @@ #include "flutter/fml/macros.h" #include "flutter/impeller/aiks/picture.h" #include "flutter/impeller/golden_tests/metal_screenshot.h" +#include "flutter/impeller/golden_tests/screenshotter.h" #include "flutter/impeller/playground/playground_impl.h" namespace impeller { @@ -15,17 +16,17 @@ namespace testing { /// Converts `Picture`s and `DisplayList`s to `MetalScreenshot`s with the /// playground backend. -class MetalScreenshotter { +class MetalScreenshotter : public Screenshotter { public: MetalScreenshotter(); - std::unique_ptr MakeScreenshot(AiksContext& aiks_context, - const Picture& picture, - const ISize& size = {300, - 300}, - bool scale_content = true); + std::unique_ptr MakeScreenshot( + AiksContext& aiks_context, + const Picture& picture, + const ISize& size = {300, 300}, + bool scale_content = true) override; - PlaygroundImpl& GetPlayground() { return *playground_; } + PlaygroundImpl& GetPlayground() override { return *playground_; } private: std::unique_ptr playground_; diff --git a/engine/src/flutter/impeller/golden_tests/metal_screenshotter.mm b/engine/src/flutter/impeller/golden_tests/metal_screenshotter.mm index 5cd6e0014c..7e17b3f7b0 100644 --- a/engine/src/flutter/impeller/golden_tests/metal_screenshotter.mm +++ b/engine/src/flutter/impeller/golden_tests/metal_screenshotter.mm @@ -19,7 +19,7 @@ MetalScreenshotter::MetalScreenshotter() { PlaygroundImpl::Create(PlaygroundBackend::kMetal, PlaygroundSwitches{}); } -std::unique_ptr MetalScreenshotter::MakeScreenshot( +std::unique_ptr MetalScreenshotter::MakeScreenshot( AiksContext& aiks_context, const Picture& picture, const ISize& size, diff --git a/engine/src/flutter/impeller/golden_tests/screenshot.h b/engine/src/flutter/impeller/golden_tests/screenshot.h new file mode 100644 index 0000000000..4772609b2f --- /dev/null +++ b/engine/src/flutter/impeller/golden_tests/screenshot.h @@ -0,0 +1,40 @@ +// 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_IMPELLER_GOLDEN_TESTS_SCREENSHOT_H_ +#define FLUTTER_IMPELLER_GOLDEN_TESTS_SCREENSHOT_H_ + +#include +#include +#include +#include + +namespace impeller { +namespace testing { + +class Screenshot { + public: + virtual ~Screenshot() = default; + + /// Access raw data of the screenshot. + virtual const uint8_t* GetBytes() const = 0; + + /// Returns the height of the image in pixels. + virtual size_t GetHeight() const = 0; + + /// Returns the width of the image in pixels. + virtual size_t GetWidth() const = 0; + + /// Returns number of bytes required to represent one row of the raw image. + virtual size_t GetBytesPerRow() const = 0; + + /// Synchronously write the screenshot to disk as a PNG at `path`. Returns + /// `true` if it succeeded. + virtual bool WriteToPNG(const std::string& path) const = 0; +}; + +} // namespace testing +} // namespace impeller + +#endif // FLUTTER_IMPELLER_GOLDEN_TESTS_SCREENSHOT_H_ diff --git a/engine/src/flutter/impeller/golden_tests/screenshotter.h b/engine/src/flutter/impeller/golden_tests/screenshotter.h new file mode 100644 index 0000000000..d75f607d42 --- /dev/null +++ b/engine/src/flutter/impeller/golden_tests/screenshotter.h @@ -0,0 +1,34 @@ +// 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_IMPELLER_GOLDEN_TESTS_SCREENSHOTTER_H_ +#define FLUTTER_IMPELLER_GOLDEN_TESTS_SCREENSHOTTER_H_ + +#include "flutter/fml/macros.h" +#include "flutter/impeller/aiks/picture.h" +#include "flutter/impeller/golden_tests/screenshot.h" +#include "flutter/impeller/playground/playground_impl.h" + +namespace impeller { +namespace testing { + +/// Converts `Picture`s and `DisplayList`s to `MetalScreenshot`s with the +/// playground backend. +class Screenshotter { + public: + virtual ~Screenshotter() = default; + + virtual std::unique_ptr MakeScreenshot( + AiksContext& aiks_context, + const Picture& picture, + const ISize& size = {300, 300}, + bool scale_content = true) = 0; + + virtual PlaygroundImpl& GetPlayground() = 0; +}; + +} // namespace testing +} // namespace impeller + +#endif // FLUTTER_IMPELLER_GOLDEN_TESTS_SCREENSHOTTER_H_ diff --git a/engine/src/flutter/impeller/golden_tests/vulkan_screenshotter.h b/engine/src/flutter/impeller/golden_tests/vulkan_screenshotter.h new file mode 100644 index 0000000000..78d8e639f9 --- /dev/null +++ b/engine/src/flutter/impeller/golden_tests/vulkan_screenshotter.h @@ -0,0 +1,38 @@ +// 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_IMPELLER_GOLDEN_TESTS_VULKAN_SCREENSHOTTER_H_ +#define FLUTTER_IMPELLER_GOLDEN_TESTS_VULKAN_SCREENSHOTTER_H_ + +#include "flutter/fml/macros.h" +#include "flutter/impeller/aiks/picture.h" +#include "flutter/impeller/golden_tests/metal_screenshot.h" +#include "flutter/impeller/golden_tests/screenshotter.h" +#include "flutter/impeller/playground/playground_impl.h" + +namespace impeller { +namespace testing { + +/// Converts `Picture`s and `DisplayList`s to `MetalScreenshot`s with the +/// playground backend. +class VulkanScreenshotter : public Screenshotter { + public: + VulkanScreenshotter(); + + std::unique_ptr MakeScreenshot( + AiksContext& aiks_context, + const Picture& picture, + const ISize& size = {300, 300}, + bool scale_content = true) override; + + PlaygroundImpl& GetPlayground() override { return *playground_; } + + private: + std::unique_ptr playground_; +}; + +} // namespace testing +} // namespace impeller + +#endif // FLUTTER_IMPELLER_GOLDEN_TESTS_VULKAN_SCREENSHOTTER_H_ diff --git a/engine/src/flutter/impeller/golden_tests/vulkan_screenshotter.mm b/engine/src/flutter/impeller/golden_tests/vulkan_screenshotter.mm new file mode 100644 index 0000000000..5633faf832 --- /dev/null +++ b/engine/src/flutter/impeller/golden_tests/vulkan_screenshotter.mm @@ -0,0 +1,90 @@ +// 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. + +#include "flutter/impeller/golden_tests/vulkan_screenshotter.h" + +#include "flutter/fml/synchronization/waitable_event.h" +#include "flutter/impeller/golden_tests/metal_screenshot.h" +#include "impeller/renderer/backend/vulkan/surface_context_vk.h" +#include "impeller/renderer/backend/vulkan/texture_vk.h" +#define GLFW_INCLUDE_NONE +#include "third_party/glfw/include/GLFW/glfw3.h" + +namespace impeller { +namespace testing { + +namespace { +std::unique_ptr ReadTexture( + const std::shared_ptr& surface_context, + const std::shared_ptr& texture) { + DeviceBufferDescriptor buffer_desc; + buffer_desc.storage_mode = StorageMode::kHostVisible; + buffer_desc.size = + texture->GetTextureDescriptor().GetByteSizeOfBaseMipLevel(); + std::shared_ptr device_buffer = + surface_context->GetResourceAllocator()->CreateBuffer(buffer_desc); + FML_CHECK(device_buffer); + + auto command_buffer = surface_context->CreateCommandBuffer(); + auto blit_pass = command_buffer->CreateBlitPass(); + bool success = blit_pass->AddCopy(texture, device_buffer); + FML_CHECK(success); + + success = blit_pass->EncodeCommands(surface_context->GetResourceAllocator()); + FML_CHECK(success); + + fml::AutoResetWaitableEvent latch; + success = + command_buffer->SubmitCommands([&latch](CommandBuffer::Status status) { + FML_CHECK(status == CommandBuffer::Status::kCompleted); + latch.Signal(); + }); + FML_CHECK(success); + latch.Wait(); + + // TODO(gaaclarke): Replace CoreImage requirement with something + // crossplatform. + + CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB(); + CGBitmapInfo bitmap_info = + kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little; + CGContextRef context = CGBitmapContextCreate( + device_buffer->OnGetContents(), texture->GetSize().width, + texture->GetSize().height, + /*bitsPerComponent=*/8, + /*bytesPerRow=*/texture->GetTextureDescriptor().GetBytesPerRow(), + color_space, bitmap_info); + FML_CHECK(context); + CGImageRef image_ref = CGBitmapContextCreateImage(context); + FML_CHECK(image_ref); + CGContextRelease(context); + CGColorSpaceRelease(color_space); + return std::make_unique(image_ref); +} +} // namespace + +VulkanScreenshotter::VulkanScreenshotter() { + FML_CHECK(::glfwInit() == GLFW_TRUE); + playground_ = + PlaygroundImpl::Create(PlaygroundBackend::kVulkan, PlaygroundSwitches{}); +} + +std::unique_ptr VulkanScreenshotter::MakeScreenshot( + AiksContext& aiks_context, + const Picture& picture, + const ISize& size, + bool scale_content) { + Vector2 content_scale = + scale_content ? playground_->GetContentScale() : Vector2{1, 1}; + std::shared_ptr image = picture.ToImage( + aiks_context, + ISize(size.width * content_scale.x, size.height * content_scale.y)); + std::shared_ptr texture = image->GetTexture(); + FML_CHECK(aiks_context.GetContext()->GetBackendType() == + Context::BackendType::kVulkan); + return ReadTexture(aiks_context.GetContext(), texture); +} + +} // namespace testing +} // namespace impeller diff --git a/engine/src/flutter/impeller/playground/backend/vulkan/playground_impl_vk.cc b/engine/src/flutter/impeller/playground/backend/vulkan/playground_impl_vk.cc index d05004f4eb..068cf2e56a 100644 --- a/engine/src/flutter/impeller/playground/backend/vulkan/playground_impl_vk.cc +++ b/engine/src/flutter/impeller/playground/backend/vulkan/playground_impl_vk.cc @@ -175,8 +175,39 @@ void PlaygroundImplVK::InitGlobalVulkanInstance() { application_info.setPEngineName("PlaygroundImplVK"); application_info.setPApplicationName("PlaygroundImplVK"); - auto instance_result = - vk::createInstanceUnique(vk::InstanceCreateInfo({}, &application_info)); + auto caps = std::shared_ptr( + new CapabilitiesVK(/*enable_validations=*/true)); + FML_DCHECK(caps->IsValid()); + + std::optional> enabled_layers = + caps->GetEnabledLayers(); + std::optional> enabled_extensions = + caps->GetEnabledInstanceExtensions(); + FML_DCHECK(enabled_layers.has_value() && enabled_extensions.has_value()); + + std::vector enabled_layers_c; + std::vector enabled_extensions_c; + + if (enabled_layers.has_value()) { + for (const auto& layer : enabled_layers.value()) { + enabled_layers_c.push_back(layer.c_str()); + } + } + + if (enabled_extensions.has_value()) { + for (const auto& ext : enabled_extensions.value()) { + enabled_extensions_c.push_back(ext.c_str()); + } + } + + vk::InstanceCreateFlags instance_flags = {}; + instance_flags |= vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR; + vk::InstanceCreateInfo instance_info; + instance_info.setPEnabledLayerNames(enabled_layers_c); + instance_info.setPEnabledExtensionNames(enabled_extensions_c); + instance_info.setPApplicationInfo(&application_info); + instance_info.setFlags(instance_flags); + auto instance_result = vk::createInstanceUnique(instance_info); FML_CHECK(instance_result.result == vk::Result::eSuccess) << "Unable to initialize global Vulkan instance"; global_instance_ = std::move(instance_result.value); diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/formats_vk.h b/engine/src/flutter/impeller/renderer/backend/vulkan/formats_vk.h index bf0ce5fb6a..9e39a5906f 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/formats_vk.h +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/formats_vk.h @@ -224,7 +224,6 @@ constexpr vk::Filter ToVKSamplerMinMagFilter(MinMagFilter filter) { } constexpr vk::SamplerMipmapMode ToVKSamplerMipmapMode(MipFilter filter) { - vk::SamplerCreateInfo sampler_info; switch (filter) { case MipFilter::kNearest: return vk::SamplerMipmapMode::eNearest; diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.cc b/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.cc index afc1407f6f..c0ef312fec 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.cc +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.cc @@ -115,4 +115,8 @@ vk::UniqueSurfaceKHR SurfaceContextVK::CreateAndroidSurface( #endif // FML_OS_ANDROID +const vk::Device& SurfaceContextVK::GetDevice() const { + return parent_->GetDevice(); +} + } // namespace impeller diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.h b/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.h index 5c144759e4..cf849c576d 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.h +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.h @@ -76,6 +76,8 @@ class SurfaceContextVK : public Context, vk::UniqueSurfaceKHR CreateAndroidSurface(ANativeWindow* window) const; #endif // FML_OS_ANDROID + const vk::Device& GetDevice() const; + private: std::shared_ptr parent_; std::shared_ptr swapchain_; diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/texture_vk.h b/engine/src/flutter/impeller/renderer/backend/vulkan/texture_vk.h index ebe86fbf26..3ecd29c2e4 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/texture_vk.h +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/texture_vk.h @@ -35,6 +35,9 @@ class TextureVK final : public Texture, public BackendCast { std::shared_ptr GetTextureSource() const; + // |Texture| + ISize GetSize() const override; + private: std::weak_ptr context_; std::shared_ptr source_; @@ -54,9 +57,6 @@ class TextureVK final : public Texture, public BackendCast { // |Texture| bool IsValid() const override; - // |Texture| - ISize GetSize() const override; - TextureVK(const TextureVK&) = delete; TextureVK& operator=(const TextureVK&) = delete;