Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
vulkan_screenshotter.mm
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#define GLFW_INCLUDE_NONE
10
11namespace impeller {
12namespace testing {
13
14namespace {
15
16using CGContextPtr = std::unique_ptr<std::remove_pointer<CGContextRef>::type,
17 decltype(&CGContextRelease)>;
18using CGImagePtr = std::unique_ptr<std::remove_pointer<CGImageRef>::type,
19 decltype(&CGImageRelease)>;
20using CGColorSpacePtr =
21 std::unique_ptr<std::remove_pointer<CGColorSpaceRef>::type,
22 decltype(&CGColorSpaceRelease)>;
23
24std::unique_ptr<Screenshot> ReadTexture(
25 const std::shared_ptr<Context>& surface_context,
26 const std::shared_ptr<Texture>& texture) {
27 DeviceBufferDescriptor buffer_desc;
28 buffer_desc.storage_mode = StorageMode::kHostVisible;
29 buffer_desc.size =
30 texture->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
31 buffer_desc.readback = true;
32 std::shared_ptr<DeviceBuffer> device_buffer =
33 surface_context->GetResourceAllocator()->CreateBuffer(buffer_desc);
34 FML_CHECK(device_buffer);
35
36 auto command_buffer = surface_context->CreateCommandBuffer();
37 auto blit_pass = command_buffer->CreateBlitPass();
38 bool success = blit_pass->AddCopy(texture, device_buffer);
39 FML_CHECK(success);
40
41 success = blit_pass->EncodeCommands();
42 FML_CHECK(success);
43
45 success =
46 surface_context->GetCommandQueue()
47 ->Submit({command_buffer},
48 [&latch](CommandBuffer::Status status) {
50 latch.Signal();
51 })
52 .ok();
53 FML_CHECK(success);
54 latch.Wait();
55 device_buffer->Invalidate();
56
57 // TODO(gaaclarke): Replace CoreImage requirement with something
58 // crossplatform.
59
60 CGColorSpacePtr color_space(CGColorSpaceCreateDeviceRGB(),
61 &CGColorSpaceRelease);
62 CGBitmapInfo bitmap_info =
63 texture->GetTextureDescriptor().format == PixelFormat::kB8G8R8A8UNormInt
64 ? static_cast<uint32_t>(kCGImageAlphaPremultipliedFirst) |
65 static_cast<uint32_t>(kCGBitmapByteOrder32Little)
66 : kCGImageAlphaPremultipliedLast;
67 CGContextPtr context(
68 CGBitmapContextCreate(
69 device_buffer->OnGetContents(), texture->GetSize().width,
70 texture->GetSize().height,
71 /*bitsPerComponent=*/8,
72 /*bytesPerRow=*/texture->GetTextureDescriptor().GetBytesPerRow(),
73 color_space.get(), bitmap_info),
74 &CGContextRelease);
76 CGImagePtr image(CGBitmapContextCreateImage(context.get()), &CGImageRelease);
78
79 return std::make_unique<MetalScreenshot>(image.release());
80}
81} // namespace
82
84
85std::unique_ptr<Screenshot> VulkanScreenshotter::MakeScreenshot(
86 const std::shared_ptr<Context>& context,
87 const std::shared_ptr<Texture>& texture) {
88 return ReadTexture(context, texture);
89}
90
91std::unique_ptr<Screenshot> Screenshotter::MakeOpenGLScreenshot(
92 std::shared_ptr<Context>& context,
93 const std::shared_ptr<Texture>& texture) {
94 return ReadTexture(context, texture);
95}
96
97std::unique_ptr<Screenshot> Screenshotter::MakeVulkanScreenshot(
98 std::shared_ptr<Context>& context,
99 const std::shared_ptr<Texture>& texture) {
100 return ReadTexture(context, texture);
101}
102
103std::unique_ptr<Screenshot> VulkanScreenshotter::MakeScreenshot(
104 const AiksContext& aiks_context,
105 const std::shared_ptr<Texture>& texture) {
106 return ReadTexture(aiks_context.GetContext(), texture);
107}
108
109} // namespace testing
110} // namespace impeller
std::shared_ptr< Context > GetContext() const
static std::unique_ptr< Screenshot > MakeScreenshot(const std::shared_ptr< Context > &context, const std::shared_ptr< Texture > &texture)
FlutterVulkanImage * image
#define FML_CHECK(condition)
Definition logging.h:104
FlTexture * texture
std::shared_ptr< ContextGLES > context
std::shared_ptr< CommandBuffer > command_buffer