diff --git a/packages/skia/cpp/api/JsiSkCanvas.h b/packages/skia/cpp/api/JsiSkCanvas.h index 19be01b60a..a5270cabd7 100644 --- a/packages/skia/cpp/api/JsiSkCanvas.h +++ b/packages/skia/cpp/api/JsiSkCanvas.h @@ -6,6 +6,7 @@ #include #include "JsiSkConverters.h" +#include "JsiSkDispatcher.h" #include "JsiSkFont.h" #include "JsiSkImage.h" #include "JsiSkImageInfo.h" @@ -607,16 +608,31 @@ class JsiSkCanvas : public JsiSkNativeObject { setCanvas(canvas); } + ~JsiSkCanvas() override { + // This destructor can run on any thread (GC), and a surface must be + // released on the thread it was created on. + if (_surface && _dispatcher) { + _dispatcher->run([surface = std::move(_surface)]() {}); + } + } + void setCanvas(SkCanvas *canvas) { _canvas = canvas; } SkCanvas *getCanvas() { return _canvas; } // Optionally associate the canvas with its owning surface. This lets // readPixels fall back to a surface snapshot on Graphite, which has no // synchronous canvas readback. - void setSurface(sk_sp surface) { _surface = std::move(surface); } + void setSurface(sk_sp surface) { + _surface = std::move(surface); + // Called on the thread that owns the surface: keep its dispatcher, and + // drain it as the JsiSkImage constructor does. + _dispatcher = Dispatcher::getDispatcher(); + _dispatcher->processQueue(); + } private: SkCanvas *_canvas; sk_sp _surface; + std::shared_ptr _dispatcher; }; } // namespace RNSkia