| // 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 <memory> | |
| #include "flutter/fml/logging.h" | |
| #include "flutter/testing/test_vulkan_context.h" | |
| #include "third_party/skia/include/core/SkColorSpace.h" | |
| #include "third_party/skia/include/core/SkColorType.h" | |
| #include "third_party/skia/include/core/SkSurface.h" | |
| #include "third_party/skia/include/core/SkSurfaceProps.h" | |
| #include "third_party/skia/include/gpu/GrBackendSurface.h" | |
| #include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h" | |
| #include "third_party/skia/include/gpu/ganesh/vk/GrVkBackendSurface.h" | |
| #include "third_party/skia/include/gpu/vk/GrVkTypes.h" | |
| namespace flutter { | |
| namespace testing { | |
| TestVulkanSurface::TestVulkanSurface(TestVulkanImage&& image) | |
| : image_(std::move(image)){}; | |
| std::unique_ptr<TestVulkanSurface> TestVulkanSurface::Create( | |
| const TestVulkanContext& context, | |
| const SkISize& surface_size) { | |
| auto image_result = context.CreateImage(surface_size); | |
| if (!image_result.has_value()) { | |
| FML_LOG(ERROR) << "Could not create VkImage."; | |
| return nullptr; | |
| } | |
| GrVkImageInfo image_info = { | |
| .fImage = image_result.value().GetImage(), | |
| .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, | |
| }; | |
| auto backend_texture = GrBackendTextures::MakeVk( | |
| surface_size.width(), surface_size.height(), image_info); | |
| SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry); | |
| auto result = std::unique_ptr<TestVulkanSurface>( | |
| new TestVulkanSurface(std::move(image_result.value()))); | |
| result->surface_ = SkSurfaces::WrapBackendTexture( | |
| 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 (!result->surface_) { | |
| FML_LOG(ERROR) | |
| << "Could not wrap VkImage as an SkSurface Vulkan render texture."; | |
| return nullptr; | |
| } | |
| return result; | |
| } | |
| 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; | |
| } | |
| VkImage TestVulkanSurface::GetImage() { | |
| return image_.GetImage(); | |
| } | |
| } // namespace testing | |
| } // namespace flutter |