5
5
#include " flutter/shell/platform/embedder/tests/embedder_test_backingstore_producer.h"
6
6
7
7
#include " flutter/fml/logging.h"
8
+ #include " include/core/SkImageInfo.h"
9
+ #include " include/core/SkSize.h"
8
10
#include " third_party/skia/include/core/SkSurface.h"
9
11
12
+ #include < memory>
13
+
10
14
namespace flutter {
11
15
namespace testing {
12
16
13
17
EmbedderTestBackingStoreProducer::EmbedderTestBackingStoreProducer (
14
18
sk_sp<GrDirectContext> context,
15
19
RenderTargetType type)
16
- : context_(context), type_(type) {}
20
+ : context_(context),
21
+ type_ (type)
22
+ #ifdef SHELL_ENABLE_METAL
23
+ ,
24
+ test_metal_context_ (std::make_unique<TestMetalContext>())
25
+ #endif
26
+ {
27
+ }
17
28
18
29
EmbedderTestBackingStoreProducer::~EmbedderTestBackingStoreProducer () = default ;
19
30
@@ -28,6 +39,10 @@ bool EmbedderTestBackingStoreProducer::Create(
28
39
return CreateTexture (config, renderer_out);
29
40
case RenderTargetType::kOpenGLFramebuffer :
30
41
return CreateFramebuffer (config, renderer_out);
42
+ #endif
43
+ #ifdef SHELL_ENABLE_METAL
44
+ case RenderTargetType::kMetalTexture :
45
+ return CreateMTLTexture (config, renderer_out);
31
46
#endif
32
47
default :
33
48
return false ;
@@ -174,5 +189,52 @@ bool EmbedderTestBackingStoreProducer::CreateSoftware(
174
189
return true ;
175
190
}
176
191
192
+ bool EmbedderTestBackingStoreProducer::CreateMTLTexture (
193
+ const FlutterBackingStoreConfig* config,
194
+ FlutterBackingStore* backing_store_out) {
195
+ #ifdef SHELL_ENABLE_METAL
196
+ // TODO(gw280): Use SkSurface::MakeRenderTarget instead of generating our
197
+ // own MTLTexture and wrapping it.
198
+ auto surface_size = SkISize::Make (config->size .width , config->size .height );
199
+ auto texture_info = test_metal_context_->CreateMetalTexture (surface_size);
200
+ sk_cf_obj<FlutterMetalTextureHandle> texture;
201
+ texture.retain (texture_info.texture );
202
+
203
+ GrMtlTextureInfo skia_texture_info;
204
+ skia_texture_info.fTexture = texture;
205
+ GrBackendTexture backend_texture (surface_size.width (), surface_size.height (),
206
+ GrMipmapped::kNo , skia_texture_info);
207
+
208
+ SkSurface::TextureReleaseProc release_mtltexture = [](void * user_data) {
209
+ SkCFSafeRelease (user_data);
210
+ };
211
+
212
+ sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTexture (
213
+ context_.get (), backend_texture, kTopLeft_GrSurfaceOrigin , 1 ,
214
+ kBGRA_8888_SkColorType , nullptr , nullptr , release_mtltexture,
215
+ texture_info.texture );
216
+
217
+ if (!surface) {
218
+ FML_LOG (ERROR) << " Could not create Skia surface from a Metal texture." ;
219
+ return false ;
220
+ }
221
+
222
+ backing_store_out->type = kFlutterBackingStoreTypeMetal ;
223
+ backing_store_out->user_data = surface.get ();
224
+ backing_store_out->metal .texture .texture = texture_info.texture ;
225
+ // The balancing unref is in the destruction callback.
226
+ surface->ref ();
227
+ backing_store_out->metal .struct_size = sizeof (FlutterMetalBackingStore);
228
+ backing_store_out->metal .texture .user_data = surface.get ();
229
+ backing_store_out->metal .texture .destruction_callback = [](void * user_data) {
230
+ reinterpret_cast <SkSurface*>(user_data)->unref ();
231
+ };
232
+
233
+ return true ;
234
+ #else
235
+ return false ;
236
+ #endif
237
+ }
238
+
177
239
} // namespace testing
178
240
} // namespace flutter
0 commit comments