28 impeller::vk::ImageView image_view,
35 impeller::vk::Image GetImage()
const override {
return image_; }
37 impeller::vk::ImageView GetImageView()
const override {
return image_view_; }
39 impeller::vk::ImageView GetRenderTargetView()
const override {
43 bool IsSwapchainImage()
const override {
return true; }
45 impeller::vk::Image image_;
46 impeller::vk::ImageView image_view_;
51 std::shared_ptr<impeller::Context> context)
53 if (!context || !context->IsValid()) {
57 auto aiks_context = std::make_shared<impeller::AiksContext>(
59 if (!aiks_context->IsValid()) {
63 impeller_context_ = std::move(context);
64 aiks_context_ = std::move(aiks_context);
65 is_valid_ = !!aiks_context_;
77std::unique_ptr<SurfaceFrame> GPUSurfaceVulkanImpeller::AcquireFrame(
80 FML_LOG(ERROR) <<
"Vulkan surface was invalid.";
85 FML_LOG(ERROR) <<
"Vulkan surface was asked for an empty frame.";
89 if (delegate_ ==
nullptr) {
91 std::unique_ptr<impeller::Surface>
surface =
92 context_vk.AcquireNextSurface();
95 FML_LOG(ERROR) <<
"No surface available.";
107 ](SurfaceFrame& surface_frame,
DlCanvas* canvas)
mutable ->
bool {
112 auto display_list = surface_frame.BuildDisplayList();
114 FML_LOG(ERROR) <<
"Could not build display list for surface frame.";
119 aiks_context->GetContentContext(),
123 surface_frame.submit_info().frame_boundary
127 return std::make_unique<SurfaceFrame>(
129 SurfaceFrame::FramebufferInfo{},
140 if (!flutter_image.
image) {
141 FML_LOG(ERROR) <<
"Invalid VkImage given by the embedder.";
144 impeller::vk::Format vk_format =
145 static_cast<impeller::vk::Format
>(flutter_image.
format);
146 std::optional<impeller::PixelFormat>
format =
148 if (!
format.has_value()) {
149 FML_LOG(ERROR) <<
"Unsupported pixel format: "
150 << impeller::vk::to_string(vk_format);
154 impeller::vk::Image vk_image =
155 impeller::vk::Image(
reinterpret_cast<VkImage
>(flutter_image.
image));
168 impeller::vk::ImageViewCreateInfo view_info = {};
169 view_info.viewType = impeller::vk::ImageViewType::e2D;
171 view_info.subresourceRange.aspectMask =
172 impeller::vk::ImageAspectFlagBits::eColor;
173 view_info.subresourceRange.baseMipLevel = 0u;
174 view_info.subresourceRange.baseArrayLayer = 0u;
175 view_info.subresourceRange.levelCount = 1;
176 view_info.subresourceRange.layerCount = 1;
177 view_info.image = vk_image;
179 auto [result, image_view] =
180 context_vk.
GetDevice().createImageView(view_info);
181 if (result != impeller::vk::Result::eSuccess) {
182 FML_LOG(ERROR) <<
"Failed to create image view for provided image: "
183 << impeller::vk::to_string(result);
187 if (transients_ ==
nullptr) {
188 transients_ = std::make_shared<impeller::SwapchainTransientsVK>(
189 impeller_context_, desc,
193 auto wrapped_onscreen =
194 std::make_shared<WrappedTextureSourceVK>(vk_image, image_view, desc);
196 transients_, wrapped_onscreen, [&]() ->
bool {
return true; });
205 ](SurfaceFrame& surface_frame,
DlCanvas* canvas)
mutable ->
bool {
210 auto display_list = surface_frame.BuildDisplayList();
212 FML_LOG(ERROR) <<
"Could not build display list for surface frame.";
225 [
image = flutter_image, delegate = delegate_,
226 impeller_context = impeller_context_,
227 wrapped_onscreen](
const SurfaceFrame&) ->
bool {
228 TRACE_EVENT0(
"flutter",
"GPUSurfaceVulkan::PresentImage");
236 auto cmd_buffer = context.CreateCommandBuffer();
238 auto vk_final_cmd_buffer =
243 impeller::vk::ImageLayout::eColorAttachmentOptimal;
246 impeller::vk::AccessFlagBits::eColorAttachmentWrite;
248 impeller::vk::PipelineStageFlagBits::eColorAttachmentOutput;
251 impeller::vk::PipelineStageFlagBits::eBottomOfPipe;
253 if (!wrapped_onscreen->SetLayout(barrier).ok()) {
257 if (!context.GetCommandQueue()->Submit({cmd_buffer}).ok()) {
262 return delegate->PresentImage(
reinterpret_cast<VkImage
>(
image.
image),
266 SurfaceFrame::FramebufferInfo framebuffer_info{.supports_readback =
true};
268 return std::make_unique<SurfaceFrame>(
nullptr,
280DlMatrix GPUSurfaceVulkanImpeller::GetRootTransformation()
const {
287GrDirectContext* GPUSurfaceVulkanImpeller::GetContext() {
293std::unique_ptr<GLContextResult>
294GPUSurfaceVulkanImpeller::MakeRenderContextCurrent() {
296 return std::make_unique<GLContextDefaultResult>(
true);
300bool GPUSurfaceVulkanImpeller::EnableRasterCache()
const {
305std::shared_ptr<impeller::AiksContext>
306GPUSurfaceVulkanImpeller::GetAiksContext()
const {
307 return aiks_context_;
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.
~GPUSurfaceVulkanImpeller() override
GPUSurfaceVulkanImpeller(GPUSurfaceVulkanDelegate *delegate, std::shared_ptr< impeller::Context > context)
std::function< bool(SurfaceFrame &surface_frame, DlCanvas *canvas)> EncodeCallback
std::function< bool(SurfaceFrame &surface_frame)> SubmitCallback
WrappedTextureSourceVK(impeller::vk::Image image, impeller::vk::ImageView image_view, impeller::TextureDescriptor desc)
~WrappedTextureSourceVK()
static SurfaceContextVK & Cast(Context &base)
vk::CommandBuffer GetCommandBuffer() const
Retrieve the native command buffer from this object.
const vk::Device & GetDevice() const
ISize GetRenderTargetSize() const
static std::unique_ptr< SurfaceVK > WrapSwapchainImage(const std::shared_ptr< SwapchainTransientsVK > &transients, const std::shared_ptr< TextureSourceVK > &swapchain_image, SwapCallback swap_callback)
Wrap the swapchain image in a Surface, which provides the additional configuration required for usage...
Abstract base class that represents a vkImage and an vkImageView.
static std::shared_ptr< TypographerContext > Make()
FlutterVulkanImage * image
uint32_t uint32_t * format
#define FML_LOG(severity)
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
internal::CopyableLambda< T > MakeCopyable(T lambda)
constexpr std::optional< PixelFormat > VkFormatToImpellerFormat(vk::Format format)
constexpr vk::Format ToVKImageFormat(PixelFormat format)
bool RenderToTarget(ContentContext &context, RenderTarget render_target, const sk_sp< flutter::DisplayList > &display_list, Rect cull_rect, bool reset_host_buffer, bool is_onscreen)
Render the provided display list to the render target.
flutter::DlCanvas DlCanvas
FlutterVulkanImageHandle image
uint32_t format
The VkFormat of the image (for example: VK_FORMAT_R8G8B8A8_UNORM).
Defines an operations and memory access barrier on a resource.
vk::CommandBuffer cmd_buffer
vk::AccessFlags src_access
vk::PipelineStageFlags dst_stage
vk::ImageLayout new_layout
vk::PipelineStageFlags src_stage
vk::AccessFlags dst_access
static constexpr TRect MakeSize(const TSize< U > &size)
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
CompressionType compression_type
#define TRACE_EVENT0(category_group, name)