This repository has been archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add test context that can be passed around, create a skia context for…
… snapshotting surfaces, create a Vulkan image wrapper for making an SkSurfaces
- Loading branch information
Showing
8 changed files
with
295 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// 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/testing/test_vulkan_context.h" | ||
#include "flutter/fml/logging.h" | ||
#include "flutter/shell/common/context_options.h" | ||
|
||
#include "include/gpu/GrDirectContext.h" | ||
#include "third_party/skia/include/core/SkSurface.h" | ||
|
||
#ifdef OS_MACOSX | ||
#define VULKAN_SO_PATH "libvk_swiftshader.dylib" | ||
#elif OS_WIN | ||
#define VULKAN_SO_PATH "vk_swiftshader.dll" | ||
#else | ||
#define VULKAN_SO_PATH "libvk_swiftshader.so" | ||
#endif | ||
|
||
namespace flutter { | ||
namespace testing { | ||
|
||
TestVulkanContext::TestVulkanContext() { | ||
// --------------------------------------------------------------------------- | ||
// Initialize basic Vulkan state using the Swiftshader ICD. | ||
// --------------------------------------------------------------------------- | ||
|
||
vk_ = fml::MakeRefCounted<vulkan::VulkanProcTable>(VULKAN_SO_PATH); | ||
if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) { | ||
FML_DLOG(ERROR) << "Proc table has not acquired mandatory proc addresses."; | ||
return; | ||
} | ||
|
||
application_ = std::unique_ptr<vulkan::VulkanApplication>( | ||
new vulkan::VulkanApplication(*vk_, "Flutter Unittests", {})); | ||
if (!application_->IsValid()) { | ||
FML_DLOG(ERROR) << "Failed to initialize basic Vulkan state."; | ||
return; | ||
} | ||
if (!vk_->AreInstanceProcsSetup()) { | ||
FML_DLOG(ERROR) << "Failed to acquire full proc table."; | ||
return; | ||
} | ||
|
||
device_ = application_->AcquireFirstCompatibleLogicalDevice(); | ||
if (!device_ || !device_->IsValid()) { | ||
FML_DLOG(ERROR) << "Failed to create compatible logical device."; | ||
return; | ||
} | ||
|
||
// --------------------------------------------------------------------------- | ||
// Create a Skia context. | ||
// For creating SkSurfaces from VkImages and snapshotting them, etc. | ||
// --------------------------------------------------------------------------- | ||
|
||
uint32_t skia_features = 0; | ||
if (!device_->GetPhysicalDeviceFeaturesSkia(&skia_features)) { | ||
FML_LOG(ERROR) << "Failed to get physical device features."; | ||
|
||
return; | ||
} | ||
|
||
auto get_proc = vk_->CreateSkiaGetProc(); | ||
if (get_proc == nullptr) { | ||
FML_LOG(ERROR) << "Failed to create Vulkan getProc for Skia."; | ||
return; | ||
} | ||
|
||
GrVkBackendContext backend_context = { | ||
.fInstance = application_->GetInstance(), | ||
.fPhysicalDevice = device_->GetPhysicalDeviceHandle(), | ||
.fDevice = device_->GetHandle(), | ||
.fQueue = device_->GetQueueHandle(), | ||
.fGraphicsQueueIndex = device_->GetGraphicsQueueIndex(), | ||
.fMinAPIVersion = VK_MAKE_VERSION(1, 0, 0), | ||
.fMaxAPIVersion = VK_MAKE_VERSION(1, 0, 0), | ||
.fFeatures = skia_features, | ||
.fGetProc = get_proc, | ||
.fOwnsInstanceAndDevice = false, | ||
}; | ||
|
||
GrContextOptions options = | ||
MakeDefaultContextOptions(ContextType::kRender, GrBackendApi::kVulkan); | ||
options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo; | ||
context_ = GrDirectContext::MakeVulkan(backend_context, options); | ||
} | ||
|
||
VkImage TestVulkanContext::CreateImage(const SkISize& size) const { | ||
assert(false); // TODO(bdero) | ||
return nullptr; | ||
} | ||
|
||
sk_sp<GrDirectContext> TestVulkanContext::GetGrDirectContext() const { | ||
return context_; | ||
} | ||
|
||
} // namespace testing | ||
} // namespace flutter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// 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_TESTING_TEST_VULKAN_CONTEXT_H_ | ||
#define FLUTTER_TESTING_TEST_VULKAN_CONTEXT_H_ | ||
|
||
#include "flutter/fml/macros.h" | ||
#include "flutter/fml/memory/ref_ptr.h" | ||
#include "flutter/vulkan/vulkan_application.h" | ||
#include "flutter/vulkan/vulkan_device.h" | ||
#include "flutter/vulkan/vulkan_proc_table.h" | ||
|
||
#include "third_party/skia/include/core/SkSize.h" | ||
#include "third_party/skia/include/gpu/GrDirectContext.h" | ||
|
||
namespace flutter { | ||
namespace testing { | ||
|
||
class TestVulkanContext { | ||
public: | ||
TestVulkanContext(); | ||
|
||
VkImage CreateImage(const SkISize& size) const; | ||
|
||
sk_sp<GrDirectContext> GetGrDirectContext() const; | ||
|
||
private: | ||
fml::RefPtr<vulkan::VulkanProcTable> vk_; | ||
std::unique_ptr<vulkan::VulkanApplication> application_; | ||
std::unique_ptr<vulkan::VulkanDevice> device_; | ||
|
||
sk_sp<GrDirectContext> context_; | ||
|
||
friend class EmbedderTestContextVulkan; | ||
friend class EmbedderConfigBuilder; | ||
|
||
FML_DISALLOW_COPY_AND_ASSIGN(TestVulkanContext); | ||
}; | ||
|
||
} // namespace testing | ||
} // namespace flutter | ||
|
||
#endif // FLUTTER_TESTING_TEST_VULKAN_CONTEXT_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// 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/testing/test_vulkan_surface.h" | ||
#include "flutter/fml/logging.h" | ||
#include "flutter/testing/test_vulkan_context.h" | ||
|
||
#include "third_party/skia/include/core/SkSurface.h" | ||
#include "third_party/skia/include/core/SkSurfaceProps.h" | ||
|
||
namespace flutter { | ||
namespace testing { | ||
|
||
TestVulkanSurface::TestVulkanSurface(const TestVulkanContext& context, | ||
const SkISize& surface_size) { | ||
VkImage image = context.CreateImage(surface_size); | ||
|
||
if (!image) { | ||
FML_LOG(ERROR) << "Could not create VkImage."; | ||
return; | ||
} | ||
|
||
GrVkImageInfo image_info = { | ||
.fImage = static_cast<VkImage>(image), | ||
.fImageTiling = VK_IMAGE_TILING_OPTIMAL, | ||
.fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, | ||
.fFormat = VK_FORMAT_R8G8B8A8_UNORM, | ||
.fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | | ||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | | ||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | | ||
VK_IMAGE_USAGE_SAMPLED_BIT, | ||
.fSampleCount = 1, | ||
.fLevelCount = 1, | ||
}; | ||
GrBackendTexture backend_texture(surface_size.width(), // | ||
surface_size.height(), // | ||
image_info // | ||
); | ||
|
||
SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry); | ||
|
||
surface_ = SkSurface::MakeFromBackendTexture( | ||
context.GetGrDirectContext().get(), // context | ||
backend_texture, // back-end texture | ||
kTopLeft_GrSurfaceOrigin, // surface origin | ||
1, // sample count | ||
kRGBA_8888_SkColorType, // color type | ||
SkColorSpace::MakeSRGB(), // color space | ||
&surface_properties, // surface properties | ||
nullptr, // release proc | ||
nullptr // release context | ||
); | ||
|
||
if (!surface_) { | ||
FML_LOG(ERROR) | ||
<< "Could not wrap VkImage as an SkSurface Vulkan render texture."; | ||
return; | ||
} | ||
} | ||
|
||
bool TestVulkanSurface::IsValid() const { | ||
return surface_ != nullptr; | ||
} | ||
|
||
sk_sp<SkImage> TestVulkanSurface::GetSurfaceSnapshot() const { | ||
if (!IsValid()) { | ||
return nullptr; | ||
} | ||
|
||
if (!surface_) { | ||
FML_LOG(ERROR) << "Aborting snapshot because of on-screen surface " | ||
"acquisition failure."; | ||
return nullptr; | ||
} | ||
|
||
auto device_snapshot = surface_->makeImageSnapshot(); | ||
|
||
if (!device_snapshot) { | ||
FML_LOG(ERROR) << "Could not create the device snapshot while attempting " | ||
"to snapshot the Vulkan surface."; | ||
return nullptr; | ||
} | ||
|
||
auto host_snapshot = device_snapshot->makeRasterImage(); | ||
|
||
if (!host_snapshot) { | ||
FML_LOG(ERROR) << "Could not create the host snapshot while attempting to " | ||
"snapshot the Vulkan surface."; | ||
return nullptr; | ||
} | ||
|
||
return host_snapshot; | ||
} | ||
|
||
} // namespace testing | ||
} // namespace flutter |
Oops, something went wrong.