5
5
#include " flutter/shell/gpu/gpu_surface_vulkan.h"
6
6
7
7
#include " flutter/fml/logging.h"
8
+ #include " fml/trace_event.h"
9
+ #include " include/core/SkSize.h"
8
10
9
11
namespace flutter {
10
12
@@ -23,42 +25,57 @@ bool GPUSurfaceVulkan::IsValid() {
23
25
}
24
26
25
27
std::unique_ptr<SurfaceFrame> GPUSurfaceVulkan::AcquireFrame (
26
- const SkISize& size) {
27
- VkImage image = delegate_->AcquireImage (size);
28
+ const SkISize& frame_size) {
29
+ if (!IsValid ()) {
30
+ FML_LOG (ERROR) << " Vulkan surface was invalid." ;
31
+ return nullptr ;
32
+ }
33
+
34
+ if (frame_size.isEmpty ()) {
35
+ FML_LOG (ERROR) << " Vulkan surface was asked for an empty frame." ;
36
+ return nullptr ;
37
+ }
28
38
29
- // TODO(38466): Refactor GPU surface APIs take into account the fact that an
30
- // external view embedder may want to render to the root surface.
31
39
if (!render_to_surface_) {
32
40
return std::make_unique<SurfaceFrame>(
33
- nullptr , std::move (framebuffer_info ),
41
+ nullptr , SurfaceFrame::FramebufferInfo ( ),
34
42
[](const SurfaceFrame& surface_frame, SkCanvas* canvas) {
35
43
return true ;
36
44
});
37
45
}
38
46
39
- sk_sp<SkSurface> surface = window_.AcquireSurface ();
47
+ VkImage image = delegate_->AcquireImage (frame_size);
48
+ if (!image) {
49
+ FML_LOG (ERROR) << " Invalid VkImage given by the embedder." ;
50
+ return nullptr ;
51
+ }
40
52
41
- if (surface == nullptr ) {
53
+ sk_sp<SkSurface> surface = CreateSurfaceFromVulkanImage (image, frame_size);
54
+ if (!surface) {
55
+ FML_LOG (ERROR) << " Could not create the SkSurface from the Vulkan image." ;
42
56
return nullptr ;
43
57
}
44
58
45
- SurfaceFrame::SubmitCallback callback =
46
- [weak_this = weak_factory_.GetWeakPtr ()](const SurfaceFrame&,
47
- SkCanvas* canvas) -> bool {
48
- // Frames are only ever acquired on the raster thread. This is also the
49
- // thread on which the weak pointer factory is collected (as this instance
50
- // is owned by the rasterizer). So this use of weak pointers is safe.
51
- if (canvas == nullptr || !weak_this) {
59
+ SurfaceFrame::SubmitCallback callback = [image = image, delegate = delegate_](
60
+ const SurfaceFrame&,
61
+ SkCanvas* canvas) -> bool {
62
+ TRACE_EVENT0 (" flutter" , " GPUSurfaceVulkan::PresentImage" );
63
+ if (canvas == nullptr ) {
64
+ FML_DLOG (ERROR) << " Canvas not available." ;
52
65
return false ;
53
66
}
54
- return weak_this->Present ();
67
+
68
+ canvas->flush ();
69
+
70
+ return delegate->PresentImage (image);
55
71
};
72
+
73
+ SurfaceFrame::FramebufferInfo framebuffer_info{.supports_readback = true };
74
+
56
75
return std::make_unique<SurfaceFrame>(
57
76
std::move (surface), std::move (framebuffer_info), std::move (callback));
58
77
}
59
78
60
- bool GPUSurfaceVulkan::Present () {}
61
-
62
79
SkMatrix GPUSurfaceVulkan::GetRootTransformation () const {
63
80
// This backend does not support delegating to the underlying platform to
64
81
// query for root surface transformations. Just return identity.
@@ -71,7 +88,37 @@ GrDirectContext* GPUSurfaceVulkan::GetContext() {
71
88
return skia_context_.get ();
72
89
}
73
90
74
- sk_sp<SkSurface> GPUSurfaceVulkan::AcquireSurfaceFromVulkanImage (
75
- VkImage image) {}
91
+ sk_sp<SkSurface> GPUSurfaceVulkan::CreateSurfaceFromVulkanImage (
92
+ VkImage image,
93
+ const SkISize& size) {
94
+ GrVkImageInfo image_info = {
95
+ .fImage = image,
96
+ .fImageTiling = VK_IMAGE_TILING_OPTIMAL,
97
+ .fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
98
+ .fFormat = VK_FORMAT_R8G8B8A8_UNORM,
99
+ .fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
100
+ VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
101
+ VK_IMAGE_USAGE_TRANSFER_DST_BIT |
102
+ VK_IMAGE_USAGE_SAMPLED_BIT,
103
+ .fSampleCount = 1 ,
104
+ .fLevelCount = 1 ,
105
+ };
106
+ GrBackendTexture backend_texture (size.width (), //
107
+ size.height (), //
108
+ image_info //
109
+ );
110
+
111
+ SkSurfaceProps surface_properties (0 , kUnknown_SkPixelGeometry );
112
+
113
+ return SkSurface::MakeFromBackendTexture (
114
+ skia_context_.get (), // context
115
+ backend_texture, // back-end texture
116
+ kTopLeft_GrSurfaceOrigin , // surface origin
117
+ 1 , // sample count
118
+ kRGBA_8888_SkColorType , // color type
119
+ SkColorSpace::MakeSRGB (), // color space
120
+ &surface_properties // surface properties
121
+ );
122
+ }
76
123
77
124
} // namespace flutter
0 commit comments