From fbcea4d10f64001b58eb47d9aa546281dd4911d0 Mon Sep 17 00:00:00 2001 From: Afonso Jorge Ramos Date: Fri, 28 Aug 2026 15:46:53 +0200 Subject: [PATCH] =?UTF-8?q?fix(=F0=9F=92=A3):=20guard=20the=20picture=20sw?= =?UTF-8?q?ap=20in=20RNSkPictureRenderer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/skia/cpp/rnskia/RNSkPictureView.h | 24 +++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/skia/cpp/rnskia/RNSkPictureView.h b/packages/skia/cpp/rnskia/RNSkPictureView.h index 5535f8fb30..efca635877 100644 --- a/packages/skia/cpp/rnskia/RNSkPictureView.h +++ b/packages/skia/cpp/rnskia/RNSkPictureView.h @@ -52,17 +52,30 @@ class RNSkPictureRenderer } void setPicture(sk_sp picture) { - _picture = picture; + { + std::lock_guard lock(_pictureMutex); + _picture = std::move(picture); + } _requestRedraw(); } - sk_sp getPicture() const { return _picture; } + sk_sp getPicture() const { + std::lock_guard lock(_pictureMutex); + return _picture; + } private: bool performDraw(std::shared_ptr canvasProvider) { - // Capture picture pointer to ensure thread safety - _picture can be - // modified from the JS thread while we're drawing on the render thread - sk_sp picture = _picture; + // Copy under the lock: _picture can be replaced from the JS thread while + // the render thread draws, and copying an sk_sp is not atomic. Without + // the lock, this copy can ref a picture whose count the replacement on + // the other thread has already taken to zero, and drawing it fails in + // __cxa_pure_virtual. + sk_sp picture; + { + std::lock_guard lock(_pictureMutex); + picture = _picture; + } auto pd = _platformContext->getPixelDensity(); return canvasProvider->renderToCanvas([=](SkCanvas *canvas) { canvas->clear(SK_ColorTRANSPARENT); @@ -77,6 +90,7 @@ class RNSkPictureRenderer std::shared_ptr _platformContext; sk_sp _picture; + mutable std::mutex _pictureMutex; }; class RNSkPictureView : public RNSkView {