Skip to content

Commit

Permalink
[embedder] Ensure FlutterMetalTexture cleanup call
Browse files Browse the repository at this point in the history
This ensures FlutterMetalTexture.destruction_callback gets called.

FlutterRendererConfig.get_next_drawable_callback` holds a callback used
by the embedder API to request a drawable; in the case of Metal, this
drawable is a FlutterMetalTexture.

FlutterMetalTexture.destruction_callback should be called when it's safe
to release resources associated with the FlutterMetalTexture. This
callback is not currently invoked for textures returned via
FlutterRendererConfig.get_next_drawable_callback; instead we unpack the
returned struct and pass it on.

In the compositor codepath, we do create an SkSurface that triggers the
destruction callback, here:
https://github.com/flutter/engine/blob/303e26e96561d9b76f2344e97a5fc32eb6dfdb9a/shell/platform/embedder/embedder.cc#L868-L881

Issue: flutter/flutter#116381
  • Loading branch information
cbracken committed Dec 3, 2022
1 parent f7df812 commit 7af0c70
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 8 deletions.
4 changes: 4 additions & 0 deletions shell/gpu/gpu_surface_metal_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@ typedef void* GPUCAMetalLayerHandle;
// expected to be id<MTLTexture>
typedef const void* GPUMTLTextureHandle;

typedef void (*GPUMTLDestructionCallback)(void* /* destruction_context */);

struct GPUMTLTextureInfo {
int64_t texture_id;
GPUMTLTextureHandle texture;
GPUMTLDestructionCallback destruction_callback;
void* destruction_context;
};

enum class MTLRenderTargetType { kMTLTexture, kCAMetalLayer };
Expand Down
21 changes: 13 additions & 8 deletions shell/gpu/gpu_surface_metal_skia.mm
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@
MsaaSampleCount sample_cnt,
SkColorType color_type,
sk_sp<SkColorSpace> color_space,
const SkSurfaceProps* props) {
const SkSurfaceProps* props,
SkSurface::TextureReleaseProc release_proc,
SkSurface::ReleaseContext release_context) {
GrMtlTextureInfo info;
info.fTexture.reset([texture retain]);
GrBackendTexture backend_texture(texture.width, texture.height, GrMipmapped::kNo, info);
return SkSurface::MakeFromBackendTexture(context, backend_texture, origin,
static_cast<int>(sample_cnt), color_type,
std::move(color_space), props);
return SkSurface::MakeFromBackendTexture(
context, backend_texture, origin, static_cast<int>(sample_cnt), color_type,
std::move(color_space), props, release_proc, release_context);
}
} // namespace

Expand Down Expand Up @@ -137,7 +139,9 @@
msaa_samples_, // sample count
kBGRA_8888_SkColorType, // color type
nullptr, // colorspace
nullptr // surface properties
nullptr, // surface properties
nullptr, // release proc
nullptr // release context
);

if (!surface) {
Expand Down Expand Up @@ -203,9 +207,10 @@
return nullptr;
}

sk_sp<SkSurface> surface =
CreateSurfaceFromMetalTexture(context_.get(), mtl_texture, kTopLeft_GrSurfaceOrigin,
msaa_samples_, kBGRA_8888_SkColorType, nullptr, nullptr);
sk_sp<SkSurface> surface = CreateSurfaceFromMetalTexture(
context_.get(), mtl_texture, kTopLeft_GrSurfaceOrigin, msaa_samples_, kBGRA_8888_SkColorType,
nullptr, nullptr, static_cast<SkSurface::TextureReleaseProc>(texture.destruction_callback),
texture.destruction_context);

if (!surface) {
FML_LOG(ERROR) << "Could not create the SkSurface from the metal texture.";
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/embedder/embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,8 @@ InferMetalPlatformViewCreationCallback(
FlutterMetalTexture metal_texture = ptr(user_data, &frame_info);
texture_info.texture_id = metal_texture.texture_id;
texture_info.texture = metal_texture.texture;
texture_info.destruction_callback = metal_texture.destruction_callback;
texture_info.destruction_context = metal_texture.user_data;
return texture_info;
};

Expand Down

0 comments on commit 7af0c70

Please sign in to comment.