Flutter Engine
The Flutter Engine
test_metal_context.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
5#include "flutter/testing/test_metal_context.h"
6
7#include <Metal/Metal.h>
8#include <iostream>
9
10#include "flutter/fml/logging.h"
11#include "flutter/fml/platform/darwin/scoped_nsobject.h"
16
17namespace flutter {
18
20 auto device = fml::scoped_nsprotocol{MTLCreateSystemDefaultDevice()};
21 if (!device) {
22 FML_LOG(ERROR) << "Could not acquire Metal device.";
23 return;
24 }
25
26 auto command_queue = fml::scoped_nsobject{[device.get() newCommandQueue]};
27 if (!command_queue) {
28 FML_LOG(ERROR) << "Could not create the default command queue.";
29 return;
30 }
31
32 [command_queue.get() setLabel:@"Flutter Test Queue"];
33
34 GrMtlBackendContext backendContext = {};
35 // Skia expect arguments to `MakeMetal` transfer ownership of the reference in for release later
36 // when the GrDirectContext is collected.
37 backendContext.fDevice.reset([device.get() retain]);
38 backendContext.fQueue.reset([command_queue.get() retain]);
39 skia_context_ = GrDirectContexts::MakeMetal(backendContext);
40 if (!skia_context_) {
41 FML_LOG(ERROR) << "Could not create the GrDirectContext from the Metal Device "
42 "and command queue.";
43 }
44
45 device_ = [device.get() retain];
46 command_queue_ = [command_queue.get() retain];
47}
48
50 std::scoped_lock lock(textures_mutex_);
51 textures_.clear();
52 if (device_) {
53 [(__bridge id)device_ release];
54 }
55 if (command_queue_) {
56 [(__bridge id)command_queue_ release];
57 }
58}
59
61 return device_;
62}
63
65 return command_queue_;
66}
67
69 return skia_context_;
70}
71
73 std::scoped_lock lock(textures_mutex_);
74 auto texture_descriptor = fml::scoped_nsobject{
75 [[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
76 width:size.width()
77 height:size.height()
78 mipmapped:NO] retain]};
79
80 // The most pessimistic option and disables all optimizations but allows tests
81 // the most flexible access to the surface. They may read and write to the
82 // surface from shaders or use as a pixel view.
83 texture_descriptor.get().usage = MTLTextureUsageUnknown;
84
85 if (!texture_descriptor) {
86 FML_CHECK(false) << "Invalid texture descriptor.";
87 return {.texture_id = -1, .texture = nullptr};
88 }
89
90 id<MTLDevice> device = (__bridge id<MTLDevice>)GetMetalDevice();
91 sk_cfp<void*> texture = sk_cfp<void*>{[device newTextureWithDescriptor:texture_descriptor.get()]};
92
93 if (!texture) {
94 FML_CHECK(false) << "Could not create texture from texture descriptor.";
95 return {.texture_id = -1, .texture = nullptr};
96 }
97
98 const int64_t texture_id = texture_id_ctr_++;
99 textures_[texture_id] = texture;
100
101 return {
102 .texture_id = texture_id,
103 .texture = texture.get(),
104 };
105}
106
107// Don't remove the texture from the map here.
109 std::scoped_lock lock(textures_mutex_);
110 if (textures_.find(texture_id) == textures_.end()) {
111 return false;
112 } else {
113 return true;
114 }
115}
116
118 std::scoped_lock lock(textures_mutex_);
119 if (textures_.find(texture_id) == textures_.end()) {
120 FML_CHECK(false) << "Invalid texture id: " << texture_id;
121 return {.texture_id = -1, .texture = nullptr};
122 } else {
123 return {
124 .texture_id = texture_id,
125 .texture = textures_[texture_id].get(),
126 };
127 }
128}
129
130} // namespace flutter
TextureInfo GetTextureInfo(int64_t texture_id)
sk_sp< GrDirectContext > GetSkiaContext() const
TextureInfo CreateMetalTexture(const SkISize &size)
Returns texture_id = -1 when texture creation fails.
bool Present(int64_t texture_id)
T get() const __attribute((ns_returns_not_retained))
VkDevice device
Definition: main.cc:53
#define FML_LOG(severity)
Definition: logging.h:82
#define FML_CHECK(condition)
Definition: logging.h:85
FlTexture * texture
SK_API sk_sp< GrDirectContext > MakeMetal(const GrMtlBackendContext &, const GrContextOptions &)
it will be possible to load the file into Perfetto s trace viewer 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
Definition: switches.h:259
int32_t height
int32_t width
sk_cfp< GrMTLHandle > fDevice
sk_cfp< GrMTLHandle > fQueue
Definition: SkSize.h:16
int64_t texture_id
const uintptr_t id
#define ERROR(message)
Definition: elf_loader.cc:260