Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 391c909

Browse files
committed
fix
1 parent f6c2b12 commit 391c909

File tree

3 files changed

+27
-10
lines changed

3 files changed

+27
-10
lines changed

shell/gpu/gpu_surface_metal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetal : public Surface {
2727
private:
2828
const GPUSurfaceMetalDelegate* delegate_;
2929
const MTLRenderTargetType render_target_type_;
30+
GrMTLHandle next_drawable_ = nullptr;
3031
sk_sp<GrDirectContext> context_;
3132

3233
// |Surface|
@@ -47,6 +48,8 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetal : public Surface {
4748
std::unique_ptr<SurfaceFrame> AcquireFrameFromMTLTexture(
4849
const SkISize& frame_info);
4950

51+
void ReleaseUnusedDrawableIfNecessary();
52+
5053
FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceMetal);
5154
};
5255

shell/gpu/gpu_surface_metal.mm

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include "flutter/shell/gpu/gpu_surface_metal.h"
66

77
#import <Metal/Metal.h>
8-
#include "include/core/SkSize.h"
98

109
#include "flutter/fml/make_copyable.h"
1110
#include "flutter/fml/platform/darwin/cf_utils.h"
@@ -24,7 +23,9 @@
2423
render_target_type_(delegate->GetRenderTargetType()),
2524
context_(std::move(context)) {}
2625

27-
GPUSurfaceMetal::~GPUSurfaceMetal() = default;
26+
GPUSurfaceMetal::~GPUSurfaceMetal() {
27+
ReleaseUnusedDrawableIfNecessary();
28+
}
2829

2930
// |Surface|
3031
bool GPUSurfaceMetal::IsValid() {
@@ -63,7 +64,7 @@
6364
return nullptr;
6465
}
6566

66-
GrMTLHandle drawable_raw;
67+
ReleaseUnusedDrawableIfNecessary();
6768
sk_sp<SkSurface> surface =
6869
SkSurface::MakeFromCAMetalLayer(context_.get(), // context
6970
layer, // layer
@@ -72,17 +73,16 @@
7273
kBGRA_8888_SkColorType, // color type
7374
nullptr, // colorspace
7475
nullptr, // surface properties
75-
&drawable_raw // drawable (transfer out)
76+
&next_drawable_ // drawable (transfer out)
7677
);
77-
fml::CFRef<GrMTLHandle> drawable(drawable_raw);
7878

7979
if (!surface) {
8080
FML_LOG(ERROR) << "Could not create the SkSurface from the CAMetalLayer.";
8181
return nullptr;
8282
}
8383

8484
auto submit_callback =
85-
fml::MakeCopyable([drawable = std::move(drawable), delegate = delegate_](
85+
fml::MakeCopyable([drawable = next_drawable_, delegate = delegate_](
8686
const SurfaceFrame& surface_frame, SkCanvas* canvas) -> bool {
8787
TRACE_EVENT0("flutter", "GPUSurfaceMetal::Submit");
8888
if (canvas == nullptr) {
@@ -92,6 +92,11 @@
9292

9393
canvas->flush();
9494

95+
if (!drawable) {
96+
FML_DLOG(ERROR) << "Unable to obtain a metal drawable.";
97+
return false;
98+
}
99+
95100
return delegate->PresentDrawable(drawable);
96101
});
97102

@@ -155,4 +160,16 @@
155160
return std::make_unique<GLContextDefaultResult>(true);
156161
}
157162

163+
void GPUSurfaceMetal::ReleaseUnusedDrawableIfNecessary() {
164+
// If the previous surface frame was not submitted before a new one is acquired, the old drawable
165+
// needs to be released. An RAII wrapper may not be used because this needs to interoperate with
166+
// Skia APIs.
167+
if (next_drawable_ == nullptr) {
168+
return;
169+
}
170+
171+
CFRelease(next_drawable_);
172+
next_drawable_ = nullptr;
173+
}
174+
158175
} // namespace flutter

shell/platform/darwin/ios/ios_surface_metal.mm

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,7 @@
8282
[command_buffer.get() commit];
8383
[command_buffer.get() waitUntilScheduled];
8484

85-
fml::scoped_nsprotocol<id<CAMetalDrawable>> drawable_holder(
86-
reinterpret_cast<id<CAMetalDrawable>>(drawable));
87-
[drawable_holder.get() present];
88-
85+
[reinterpret_cast<id<CAMetalDrawable>>(drawable) present];
8986
return true;
9087
}
9188

0 commit comments

Comments
 (0)