Flutter Engine
 
Loading...
Searching...
No Matches
gpu_surface_vulkan.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
9
10#include "third_party/skia/include/core/SkColorSpace.h"
11#include "third_party/skia/include/core/SkSize.h"
12#include "third_party/skia/include/core/SkSurface.h"
13#include "third_party/skia/include/gpu/ganesh/GrBackendSurface.h"
14#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h"
15#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
16#include "third_party/skia/include/gpu/ganesh/vk/GrVkBackendSurface.h"
17#include "third_party/skia/include/gpu/ganesh/vk/GrVkTypes.h"
18#include "vulkan/vulkan_core.h"
19
20namespace flutter {
21
23 const sk_sp<GrDirectContext>& skia_context,
24 bool render_to_surface)
25 : delegate_(delegate),
26 skia_context_(skia_context),
27 render_to_surface_(render_to_surface),
28 weak_factory_(this) {}
29
31
33 return skia_context_ != nullptr;
34}
35
36std::unique_ptr<SurfaceFrame> GPUSurfaceVulkan::AcquireFrame(
37 const DlISize& frame_size) {
38 if (!IsValid()) {
39 FML_LOG(ERROR) << "Vulkan surface was invalid.";
40 return nullptr;
41 }
42
43 if (frame_size.IsEmpty()) {
44 FML_LOG(ERROR) << "Vulkan surface was asked for an empty frame.";
45 return nullptr;
46 }
47
48 if (!render_to_surface_) {
49 return std::make_unique<SurfaceFrame>(
51 [](const SurfaceFrame& surface_frame, DlCanvas* canvas) {
52 return true;
53 },
54 [](const SurfaceFrame& surface_frame) { return true; }, frame_size);
55 }
56
57 FlutterVulkanImage image = delegate_->AcquireImage(frame_size);
58 if (!image.image) {
59 FML_LOG(ERROR) << "Invalid VkImage given by the embedder.";
60 return nullptr;
61 }
62
63 sk_sp<SkSurface> surface = CreateSurfaceFromVulkanImage(
64 reinterpret_cast<VkImage>(image.image),
65 static_cast<VkFormat>(image.format), frame_size);
66 if (!surface) {
67 FML_LOG(ERROR) << "Could not create the SkSurface from the Vulkan image.";
68 return nullptr;
69 }
70
71 SurfaceFrame::EncodeCallback encode_callback = [](const SurfaceFrame&,
72 DlCanvas* canvas) -> bool {
73 if (canvas == nullptr) {
74 FML_DLOG(ERROR) << "Canvas not available.";
75 return false;
76 }
77 canvas->Flush();
78 return true;
79 };
80
81 SurfaceFrame::SubmitCallback submit_callback =
82 [image = image, delegate = delegate_](const SurfaceFrame&) -> bool {
83 TRACE_EVENT0("flutter", "GPUSurfaceVulkan::PresentImage");
84 return delegate->PresentImage(reinterpret_cast<VkImage>(image.image),
85 static_cast<VkFormat>(image.format));
86 };
87
88 SurfaceFrame::FramebufferInfo framebuffer_info{.supports_readback = true};
89
90 return std::make_unique<SurfaceFrame>(std::move(surface), framebuffer_info,
91 std::move(encode_callback),
92 std::move(submit_callback), frame_size);
93}
94
96 // This backend does not support delegating to the underlying platform to
97 // query for root surface transformations. Just return identity.
98 return DlMatrix();
99}
100
102 return skia_context_.get();
103}
104
105sk_sp<SkSurface> GPUSurfaceVulkan::CreateSurfaceFromVulkanImage(
106 const VkImage image,
107 const VkFormat format,
108 const DlISize& size) {
109#ifdef SK_VULKAN
110 GrVkImageInfo image_info = {
111 .fImage = image,
112 .fImageTiling = VK_IMAGE_TILING_OPTIMAL,
113 .fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
114 .fFormat = format,
115 .fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
116 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
117 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
118 VK_IMAGE_USAGE_SAMPLED_BIT,
119 .fSampleCount = 1,
120 .fLevelCount = 1,
121 };
122 auto backend_texture =
123 GrBackendTextures::MakeVk(size.width, size.height, image_info);
124
125 SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry);
126
127 return SkSurfaces::WrapBackendTexture(
128 skia_context_.get(), // context
129 backend_texture, // back-end texture
130 kTopLeft_GrSurfaceOrigin, // surface origin
131 1, // sample count
132 ColorTypeFromFormat(format), // color type
133 SkColorSpace::MakeSRGB(), // color space
134 &surface_properties // surface properties
135 );
136#else
137 return nullptr;
138#endif // SK_VULKAN
139}
140
141SkColorType GPUSurfaceVulkan::ColorTypeFromFormat(const VkFormat format) {
142 switch (format) {
143 case VK_FORMAT_R8G8B8A8_UNORM:
144 case VK_FORMAT_R8G8B8A8_SRGB:
145 return SkColorType::kRGBA_8888_SkColorType;
146 case VK_FORMAT_B8G8R8A8_UNORM:
147 case VK_FORMAT_B8G8R8A8_SRGB:
148 return SkColorType::kBGRA_8888_SkColorType;
149 default:
150 return SkColorType::kUnknown_SkColorType;
151 }
152}
153
154} // namespace flutter
Developer-facing API for rendering anything within the engine.
Definition dl_canvas.h:32
Interface implemented by all platform surfaces that can present a Vulkan backing store to the "screen...
virtual FlutterVulkanImage AcquireImage(const DlISize &size)=0
Called by the engine to fetch a VkImage for writing the next frame.
DlMatrix GetRootTransformation() const override
GrDirectContext * GetContext() override
static SkColorType ColorTypeFromFormat(const VkFormat format)
std::unique_ptr< SurfaceFrame > AcquireFrame(const DlISize &size) override
GPUSurfaceVulkan(GPUSurfaceVulkanDelegate *delegate, const sk_sp< GrDirectContext > &context, bool render_to_surface)
Create a GPUSurfaceVulkan while letting it reuse an existing GrDirectContext.
std::function< bool(SurfaceFrame &surface_frame, DlCanvas *canvas)> EncodeCallback
std::function< bool(SurfaceFrame &surface_frame)> SubmitCallback
FlutterVulkanImage * image
MockDelegate delegate_
VkSurfaceKHR surface
Definition main.cc:65
uint32_t uint32_t * format
#define FML_DLOG(severity)
Definition logging.h:121
#define FML_LOG(severity)
Definition logging.h:101
impeller::Matrix DlMatrix
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
FlutterVulkanImageHandle image
Definition embedder.h:931
uint32_t format
The VkFormat of the image (for example: VK_FORMAT_R8G8B8A8_UNORM).
Definition embedder.h:933
A 4x4 matrix using column-major storage.
Definition matrix.h:37
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
Definition size.h:123
#define TRACE_EVENT0(category_group, name)