diff --git a/apps/example/ios/Podfile.lock b/apps/example/ios/Podfile.lock index 1883edbac6..1eee6abbfc 100644 --- a/apps/example/ios/Podfile.lock +++ b/apps/example/ios/Podfile.lock @@ -3208,88 +3208,88 @@ SPEC CHECKSUMS: fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd glog: 5683914934d5b6e4240e497e0f4a3b42d1854183 hermes-engine: 11b010917f5f15150b2c015abddef1573d2bb05d - RCT-Folly: 59ec0ac1f2f39672a0c6e6cecdd39383b764646f + RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669 RCTDeprecation: a41bbdd9af30bf2e5715796b313e44ec43eefff1 RCTRequired: 7be34aabb0b77c3cefe644528df0fa0afad4e4d0 RCTSwiftUI: a6c7271c39098bf00dbdad8f8ed997a59bbfbe44 - RCTSwiftUIWrapper: 5ec163e8fde163d3fba714a992b50a266e1ece37 + RCTSwiftUIWrapper: ff9098ccf7727e58218f2f8ea110349863f43438 RCTTypeSafety: 27927d0ca04e419ed9467578b3e6297e37210b5c React: 4bc1f928568ad4bcfd147260f907b4ea5873a03b React-callinvoker: 87f8728235a0dc62e9dc19b3851c829d9347d015 - React-Core: 19e0183e28d7a6613ecacebd7525fe6650efa3b6 - React-CoreModules: 73cc86f2a0ff84b93d6325073ad2e4874d21ad40 - React-cxxreact: 4bf734645c77c9b86e2f3e933e0411cf2f14d1ba + React-Core: 76bed73b02821e5630e7f2cb2e82432ee964695d + React-CoreModules: 752dbfdaeb096658aa0adc4a03ba6214815a08df + React-cxxreact: b6798528aa601c6db66e6adc7e2da2b059c8be74 React-debug: 8978deb306f6f38c28b5091e52b0ac9f942b157e - React-defaultsnativemodule: 724eb9ec388d494f1e2057d83355ee8fe6f1d780 - React-domnativemodule: 9068f41092f725acd09950233d2847364c731947 - React-Fabric: 945cc8abf08d9d0966acef605bffce7b501c49d9 - React-FabricComponents: 4c4ad6f0d16c964a68f945e029505e2eeec6654b - React-FabricImage: a8b628fd98db21b9f8588e06f14a9194dda11b40 - React-featureflags: 0937601c1af1cc125851ec5bbf4654285d47a3e7 - React-featureflagsnativemodule: ac1a3e0353e1a6e15411b17ed6c7122adb0468a4 - React-graphics: cca521e06463608be46207a4aa160f8a7f725f8b - React-hermes: ec50b9fcea2c3bfdd42f8cec845eac3f35888572 - React-idlecallbacksnativemodule: effcae5b7b4473211adb154aaa321d5d9e2fbcc9 - React-ImageManager: b38459e538f1840fa5c3e7612a4bcb0029a3c366 - React-intersectionobservernativemodule: 8d33366661971200cf2e151727f6fe007b62ae7b - React-jserrorhandler: f94c688a0dbe2e045b91b992722b92e97d56f77f - React-jsi: 3216c876cd4c571a57909e22d77c8fd9530aa067 - React-jsiexecutor: 475563c0042841a85930a455d3199f6b1483a5fe - React-jsinspector: bc484fb32bf1b9fed80afe8793e614eba4f7b39e - React-jsinspectorcdp: 5a574d1d35016968a67e78e6b8a7917473ffbb77 - React-jsinspectornetwork: dce3a5a1351b527ee8c28ad4a8bdd211507e1a45 - React-jsinspectortracing: 65f6b166bd67e5adc31eba027e1570bacf7a3cc7 - React-jsitooling: d5463f5489a31640b0fa0ec4e31566ca8aa86c13 - React-jsitracing: 3c7fc18821aba64855acb8658aa857ca6a7fddf6 - React-logger: 6ac901f5c7f7321d2be1a40b203bccc2e23411e3 - React-Mapbuffer: 2e0e7cc5b7064eaed9c8b8afc3a87621cb7ef5cd - React-microtasksnativemodule: dd4d33b251b57e5027c572c6d0b45cbfbcfaa386 - react-native-safe-area-context: 54d812805f3c4e08a4580ad086cbde1d8780c2e4 - react-native-skia: a2f66139c57b503a5a5b3647fc111b53bfc02590 - React-NativeModulesApple: 7f2f2fed3f6c858889eb61d09941be965d52df58 - React-networking: 43e5e6773ac2ca2a93261a1388fed269c9fce092 + React-defaultsnativemodule: 682b77ef4acfb298017be15f4f93c1d998deb174 + React-domnativemodule: 4c4b44f7eb68dbc3a2218db088bef318a7302017 + React-Fabric: b6f82a4d8498ce4475586f71ca8397a771fe292d + React-FabricComponents: c8695f4b11918a127c4560d66f7d3fdb01a17986 + React-FabricImage: d64f48830f63830e8ffaaf69fa487116856fbbf1 + React-featureflags: 2a46b229903e906d33dbaf9207ce57c59306c369 + React-featureflagsnativemodule: cba6c0814051a0934f8bcee4a436ee2a6bcc9754 + React-graphics: 3d0435051e1ab8904d065f8ffbe981a9fc202841 + React-hermes: 32fc9c231c1aa5c2fcfe851b0d19ee9269f88f4c + React-idlecallbacksnativemodule: f8ee42581795c4844d97147596bcc2d824c0f188 + React-ImageManager: e8f7377ef0585fd2df05559a17e01a03e187d5cf + React-intersectionobservernativemodule: b1bea12ca29accdd2eda60c87605a6030b894eb9 + React-jserrorhandler: 1a86df895b4eaf4e771abe8cf34cbb26d821f771 + React-jsi: adf8527fec197ad9d0480cc5b8945eb56de627f0 + React-jsiexecutor: 315fa2f879b43e3a9ca08f5f4b733472f7e4e8a4 + React-jsinspector: b4fd1933666bcb2549b566b40656c1e45e9d7632 + React-jsinspectorcdp: 80141710f2668e5b8f00417298d9b76b4abf90fa + React-jsinspectornetwork: 1d3ea717dbbec316cd8c21a0af53928a7bf74901 + React-jsinspectortracing: 4ce745374d4b2bfbd164cce9f8de8383d3d818a0 + React-jsitooling: fc4ac4c3b1f3f9f7fedf0c777c6ff3f244f568bd + React-jsitracing: bff08a6faeef4a9bd286487da191f5e5329e21a9 + React-logger: b8483fa08e0d62e430c76d864309d90576ca2f68 + React-Mapbuffer: 7b72a669e94662359dad4f42b5af005eb24b4e83 + React-microtasksnativemodule: cdc02da075f2857803ed63f24f5f72fc40e094c0 + react-native-safe-area-context: c00143b4823773bba23f2f19f85663ae89ceb460 + react-native-skia: c4007b72a1ce079c5e0862d065f3bc7b48a9105c + React-NativeModulesApple: a2c3d2cbec893956a5b3e4060322db2984fff75b + React-networking: 3f98bd96893a294376e7e03730947a08d474c380 React-oscompat: 80166b66da22e7af7fad94474e9997bd52d4c8c6 - React-perflogger: 63c90e0d8c24df87ffa14dad01aeafc352847dd0 - React-performancecdpmetrics: 5a9b81c08f75045635127d626440d9ada01e774b - React-performancetimeline: 31cebfff69ec9174b3fb54b0606fcb12ef91cbad + React-perflogger: d6797918d2b1031e91a9d8f5e7fdd2c8728fb390 + React-performancecdpmetrics: 5570be61e2f97c4741c5d432c91570e8e5a39892 + React-performancetimeline: 5763499ae1991fc18dcf416e340ce7bc829bb298 React-RCTActionSheet: 3bd5f5db9f983cf38d51bb9a7a198e2ebea94821 - React-RCTAnimation: 346865a809fa5132f6c594c8b376c6cf46b44e88 - React-RCTAppDelegate: b2d1e0d3663c987f49f45094883b9e36fcbf0181 - React-RCTBlob: 74759ebb7ff9077d19f60c301782c1f8c3eb2813 - React-RCTFabric: 7b4b14dad21ca99333ebcbc0bf5c205647a315a8 - React-RCTFBReactNativeSpec: 39151968adb68b8c59f29a8bd4223d4d7780a793 - React-RCTImage: 60763f56e8a5e45d861d7c4777e428bb820ec52a - React-RCTLinking: 52aee78b0b3163167c7fcf58f80a42943c03a056 - React-RCTNetwork: f5e1e8ae5eff6982efff6289b06ec0a76d0a6ac2 - React-RCTRuntime: 0e99199322afd372e74b95ae5c58f4e074cc2855 - React-RCTSettings: 298bb40d3412bf32e0b4f0797e48416b0b7278a1 - React-RCTText: dfb74800e27d792d1188fa975a3b9807c3362e3e - React-RCTVibration: ffe5fd4f50a835e353a3b6869eb005dab11eea44 + React-RCTAnimation: 46a9978f27dc434dbeed16afa7b82619b690a9af + React-RCTAppDelegate: 62ecd60a2b2a8cae26ce6a066bfa59cfde97af01 + React-RCTBlob: 8285c859513023ee3cc8c806d9b59d4da078c4ba + React-RCTFabric: 05ed09347e938de985052f791a6a0698816d5761 + React-RCTFBReactNativeSpec: 83ba579fca9a51e774ac32578ef5dd3262edd7e2 + React-RCTImage: a5364d0f098692cfbf5bef1e8a63e7712ecb14b7 + React-RCTLinking: 34b63b0aa0e92d30f5d7aa2c255a8f95fa75ee8f + React-RCTNetwork: 1ef88b7a5310b8f915d3556b5b247def113191ed + React-RCTRuntime: ed29cf68a46782fec891e5afe1d8d758ca6ccd9b + React-RCTSettings: 2c45623d6c0f30851a123f621eb9d32298bcbb0c + React-RCTText: 0ee70f5dc18004b4d81b2c214267c6cbec058587 + React-RCTVibration: 88557e21e7cc3fe76b5b174cba28ff45c6def997 React-rendererconsistency: d280314a3e7f0097152f89e815b4de821c2be8b9 - React-renderercss: 8a1a346f3665fd5ea7a7be7b3b9f95d4743e1180 - React-rendererdebug: af74afdfb3d6c5382ebab35562efd8eb9e690473 - React-RuntimeApple: 06e33d291e72fd0c73ac47046c3536d77d5aeedd - React-RuntimeCore: 99273d2af072062eb07f0b2d2d4a0f2de697ea14 - React-runtimeexecutor: 2063c03c18810ee57939d138142e6493333360ef - React-RuntimeHermes: 2253a7f4c8d56b449230b330b0b15383ed4b3df4 - React-runtimescheduler: ff37ac6720a943da91645c06274282ac46b71f23 - React-timing: 831d7e081ba4c332ca5cccf389b88e363f13f2b4 - React-utils: 25db6c17598c4fed22b5956d7551bb8bddf1f95b - React-webperformancenativemodule: 57e41e6193cfb815bde0b5534bef68673f1270eb - ReactAppDependencyProvider: bfb12ead469222b022a2024f32aba47ce50de512 - ReactCodegen: 9ca1bd49eee1eccf6e427e406d2163f49e9c48c0 - ReactCommon: 05ad684db7d88e194272ae26baddf6300e30b8b7 - ReactNativeHost: e7e0a518b0120f0070b3e1f13c7006d3e0e8ee13 - ReactTestApp-DevSupport: 6994b53b5b81139a8ce63e0776c726c95de079a1 + React-renderercss: f8cbf83d95c2c2bbf893d37fe50c73f046584411 + React-rendererdebug: 37216ddfcd38e49d1e92bf9052ea4bc9d7b932e5 + React-RuntimeApple: 1c0e7cb8e1c2c5775585afcaaa666ec151629a8d + React-RuntimeCore: 925fe2ca24cf8e6ed87586dbb92827306b93b83f + React-runtimeexecutor: 962dae024f6df760d029512a7d99e3f73d570935 + React-RuntimeHermes: 19a7c59ec1bc9908516f0bbc29b49425f6ec64ba + React-runtimescheduler: 62f21127cd97f4d8f164eee5150d3ce53dd36f66 + React-timing: 8757bf6fb96227c264f2d1609f4ba5c68217b8ce + React-utils: 8ab26781c2f5c2f7fafb2022c8ab39d39f231b80 + React-webperformancenativemodule: 7953b7fe519f76fa595111fe18ff3d5de131bfe9 + ReactAppDependencyProvider: 0eb286cc274abb059ee601b862ebddac2e681d01 + ReactCodegen: b8e56b780fffe6edd6405be0af4a1e3049a937f7 + ReactCommon: ac934cb340aee91282ecd6f273a26d24d4c55cae + ReactNativeHost: eef98ec49b55d88ad4cabf5a4378a12b42b551ee + ReactTestApp-DevSupport: ea18f446cff64b6c9a3e28788600c82ecf51bde6 ReactTestApp-Resources: 1bd9ff10e4c24f2ad87101a32023721ae923bccf - RNGestureHandler: 77eecab5fd636666ca73a55bb61e2f1a685b7e84 - RNReanimated: 31da8d5f1605f5367e2392748ba9f4ba6eaf1178 - RNScreens: b2a5c76af24a02a2fd71bfce42780fdd9c79cc6d - RNSVG: ea9cbf6dcdbebdfff5822b0ad9311bbc4510a0b7 - RNWorklets: 4e3230b74c2e466e608458b7f665a41825bca6c1 + RNGestureHandler: cd4be101cfa17ea6bbd438710caa02e286a84381 + RNReanimated: 132940c4c15ca2757f4f7d1fd7c9c3c01dbc4689 + RNScreens: 714e10b6b554f7dc7ad9f78dcf36dc8e3fc73415 + RNSVG: 11354d28dd6cb71a59570b68c91ba6772a2d781d + RNWorklets: f2ed333c600377955ac5ab798a14210805de846d SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 - Yoga: 5bd0956bf9cb16f75101e78b5e852c7577bc5a45 + Yoga: 5456bb010373068fc92221140921b09d126b116e PODFILE CHECKSUM: 87506345285a0371afb28b9c3e6daaa999c214f3 -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.2 diff --git a/packages/skia/android/cpp/jni/include/JniSkiaPictureView.h b/packages/skia/android/cpp/jni/include/JniSkiaPictureView.h index 616db8721e..518dfb7c03 100644 --- a/packages/skia/android/cpp/jni/include/JniSkiaPictureView.h +++ b/packages/skia/android/cpp/jni/include/JniSkiaPictureView.h @@ -18,11 +18,6 @@ #include #include -#if defined(SK_GRAPHITE) -#include "RNDawnContext.h" -#else -#include "OpenGLContext.h" -#endif #include "include/core/SkBitmap.h" #include "include/core/SkCanvas.h" #include "include/core/SkImage.h" @@ -109,11 +104,8 @@ class JniSkiaPictureView : public jni::HybridClass, } sk_sp surface; -#if defined(SK_GRAPHITE) - surface = DawnContext::getInstance().MakeOffscreen(width, height); -#else - surface = OpenGLContext::getInstance().MakeOffscreen(width, height); -#endif + auto context = getSkiaManager()->getPlatformContext(); + surface = context->makeOffscreenSurface(width, height); if (!surface) { return jni::JArrayInt::newArray(0); diff --git a/packages/skia/android/cpp/rnskia-android/OpenGLContext.h b/packages/skia/android/cpp/rnskia-android/OpenGLContext.h index 1a9ad2842a..a1d9d78306 100644 --- a/packages/skia/android/cpp/rnskia-android/OpenGLContext.h +++ b/packages/skia/android/cpp/rnskia-android/OpenGLContext.h @@ -2,8 +2,12 @@ #include "GrAHardwareBufferUtils.h" #include "OpenGLWindowContext.h" +#include "RNSkLog.h" #include "gl/Display.h" +#include +#include + #include "include/core/SkCanvas.h" #include "include/core/SkColorSpace.h" #include "include/core/SkSurface.h" @@ -50,15 +54,12 @@ class OpenGLContext { public: friend class OpenGLWindowContext; + OpenGLContext(); OpenGLContext(const OpenGLContext &) = delete; OpenGLContext &operator=(const OpenGLContext &) = delete; - static OpenGLContext &getInstance() { - static thread_local OpenGLContext instance; - return instance; - } - sk_sp MakeOffscreen(int width, int height) { + assertThread("MakeOffscreen"); auto colorType = kRGBA_8888_SkColorType; SkSurfaceProps props(0, kUnknown_SkPixelGeometry); @@ -103,6 +104,7 @@ class OpenGLContext { sk_sp MakeImageFromBuffer(void *buffer, bool requireKnownFormat = false) { + assertThread("MakeImageFromBuffer"); #if __ANDROID_API__ >= 26 const AHardwareBuffer *hardwareBuffer = static_cast(buffer); @@ -168,34 +170,54 @@ class OpenGLContext { // TODO: remove width, height std::unique_ptr MakeWindow(ANativeWindow *window) { + assertThread("MakeWindow"); auto display = OpenGLSharedContext::getInstance().getDisplay(); return std::make_unique( _directContext.get(), display, _glContext.get(), window, OpenGLSharedContext::getInstance().getConfig()); } - GrDirectContext *getDirectContext() { return _directContext.get(); } - void makeCurrent() { _glContext->makeCurrent(_glSurface.get()); } + GrDirectContext *getDirectContext() { + assertThread("getDirectContext"); + return _directContext.get(); + } + void makeCurrent() { + assertThread("makeCurrent"); + _glContext->makeCurrent(_glSurface.get()); + } private: std::unique_ptr _glContext; std::unique_ptr _glSurface; sk_sp _directContext; + std::thread::id _ownerThread; - OpenGLContext() { - auto display = OpenGLSharedContext::getInstance().getDisplay(); - auto sharedContext = OpenGLSharedContext::getInstance().getContext(); - auto glConfig = OpenGLSharedContext::getInstance().getConfig(); - _glContext = display->makeContext(glConfig, sharedContext); - _glSurface = display->makePixelBufferSurface(glConfig, 1, 1); - _glContext->makeCurrent(_glSurface.get()); - auto backendInterface = GrGLMakeNativeInterface(); - _directContext = GrDirectContexts::MakeGL(backendInterface); - - if (_directContext == nullptr) { - throw std::runtime_error("GrDirectContexts::MakeGL failed"); + void assertThread(const char *op) const { + if (_ownerThread != std::this_thread::get_id()) { + RNSkLogger::logToConsole( + "OpenGLContext %s called from a different thread. " + "The OpenGL backend is thread-affine; ensure all Skia/OpenGL calls " + "run on a single thread.", + op); + throw std::runtime_error("OpenGLContext used from multiple threads"); } } }; } // namespace RNSkia + +inline RNSkia::OpenGLContext::OpenGLContext() { + auto display = OpenGLSharedContext::getInstance().getDisplay(); + auto sharedContext = OpenGLSharedContext::getInstance().getContext(); + auto glConfig = OpenGLSharedContext::getInstance().getConfig(); + _glContext = display->makeContext(glConfig, sharedContext); + _glSurface = display->makePixelBufferSurface(glConfig, 1, 1); + _glContext->makeCurrent(_glSurface.get()); + auto backendInterface = GrGLMakeNativeInterface(); + _directContext = GrDirectContexts::MakeGL(backendInterface); + + if (_directContext == nullptr) { + throw std::runtime_error("GrDirectContexts::MakeGL failed"); + } + _ownerThread = std::this_thread::get_id(); +} diff --git a/packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.cpp b/packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.cpp index 3916c0d67a..d7b14d5da8 100644 --- a/packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.cpp +++ b/packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.cpp @@ -15,6 +15,7 @@ namespace RNSkia { sk_sp OpenGLWindowContext::getSurface() { + assertThread("getSurface"); if (_skSurface == nullptr) { _glContext->makeCurrent(_glSurface.get()); GLint stencil; @@ -52,6 +53,7 @@ sk_sp OpenGLWindowContext::getSurface() { } void OpenGLWindowContext::present() { + assertThread("present"); _glContext->makeCurrent(_glSurface.get()); _directContext->flushAndSubmit(); _glSurface->present(); diff --git a/packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.h b/packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.h index 14b228a32e..a86f5623e8 100644 --- a/packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.h +++ b/packages/skia/android/cpp/rnskia-android/OpenGLWindowContext.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -39,6 +40,7 @@ class OpenGLWindowContext : public WindowContext { : _directContext(directContext), _glContext(glContext), _window(window) { ANativeWindow_acquire(_window); _glSurface = display->makeWindowSurface(config, _window); + _ownerThread = std::this_thread::get_id(); } ~OpenGLWindowContext() override { @@ -56,6 +58,7 @@ class OpenGLWindowContext : public WindowContext { int getHeight() override { return ANativeWindow_getHeight(_window); }; void resize(int width, int height) override { + assertThread("resize"); if (_skSurface != nullptr) { // Let's make sure there is no pending work _glContext->makeCurrent(_glSurface.get()); @@ -65,11 +68,24 @@ class OpenGLWindowContext : public WindowContext { } private: + void assertThread(const char *op) const { + if (_ownerThread != std::this_thread::get_id()) { + RNSkLogger::logToConsole( + "OpenGLWindowContext %s called from a different thread. " + "The OpenGL backend is thread-affine; ensure all Skia/OpenGL calls " + "run on a single thread.", + op); + throw std::runtime_error( + "OpenGLWindowContext used from multiple threads"); + } + } + GrDirectContext *_directContext; gl::Context *_glContext = nullptr; ANativeWindow *_window; sk_sp _skSurface = nullptr; std::unique_ptr _glSurface = nullptr; + std::thread::id _ownerThread; }; } // namespace RNSkia diff --git a/packages/skia/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h b/packages/skia/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h index de83c28b58..db78f86d05 100644 --- a/packages/skia/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +++ b/packages/skia/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #if defined(SK_GRAPHITE) @@ -54,17 +55,18 @@ class RNSkAndroidPlatformContext : public RNSkPlatformContext { #if defined(SK_GRAPHITE) return DawnContext::getInstance().MakeOffscreen(width, height); #else - return OpenGLContext::getInstance().MakeOffscreen(width, height); + return getOpenGLContext().MakeOffscreen(width, height); #endif } std::shared_ptr - makeContextFromNativeSurface(void *surface, int width, int height) override { + makeContextFromNativeSurface(void *surface, int width, int height, + bool /*useP3ColorSpace*/ = true) override { #if defined(SK_GRAPHITE) return DawnContext::getInstance().MakeWindow(surface, width, height); #else auto aWindow = reinterpret_cast(surface); - return OpenGLContext::getInstance().MakeWindow(aWindow); + return getOpenGLContext().MakeWindow(aWindow); #endif } @@ -72,7 +74,7 @@ class RNSkAndroidPlatformContext : public RNSkPlatformContext { #if defined(SK_GRAPHITE) return DawnContext::getInstance().MakeImageFromBuffer(buffer); #else - return OpenGLContext::getInstance().MakeImageFromBuffer(buffer); + return getOpenGLContext().MakeImageFromBuffer(buffer); #endif } @@ -87,7 +89,7 @@ class RNSkAndroidPlatformContext : public RNSkPlatformContext { textureInfo.fProtected = texInfo.glProtected ? skgpu::Protected::kYes : skgpu::Protected::kNo; - OpenGLContext::getInstance().makeCurrent(); + getOpenGLContext().makeCurrent(); if (glIsTexture(textureInfo.fID) == GL_FALSE) { throw std::runtime_error("Invalid textureInfo"); } @@ -96,16 +98,16 @@ class RNSkAndroidPlatformContext : public RNSkPlatformContext { width, height, mipMapped ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo, textureInfo); - return SkImages::BorrowTextureFrom( - OpenGLContext::getInstance().getDirectContext(), backendTexture, - kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kUnpremul_SkAlphaType, - nullptr); + return SkImages::BorrowTextureFrom(getOpenGLContext().getDirectContext(), + backendTexture, kTopLeft_GrSurfaceOrigin, + kRGBA_8888_SkColorType, + kUnpremul_SkAlphaType, nullptr); } #endif std::shared_ptr createVideo(const std::string &url) override { auto jniVideo = _jniPlatformContext->createVideo(url); - return std::make_shared(jniVideo); + return std::make_shared(jniVideo, shared_from_this()); } void releaseNativeBuffer(uint64_t pointer) override { @@ -176,7 +178,7 @@ class RNSkAndroidPlatformContext : public RNSkPlatformContext { #if !defined(SK_GRAPHITE) GrDirectContext *getDirectContext() override { - return OpenGLContext::getInstance().getDirectContext(); + return getOpenGLContext().getDirectContext(); } const TextureInfo getTexture(sk_sp image) override { @@ -193,7 +195,7 @@ class RNSkAndroidPlatformContext : public RNSkPlatformContext { return getTextureInfo(texture); } - static TextureInfo getTextureInfo(const GrBackendTexture &texture) { + TextureInfo getTextureInfo(const GrBackendTexture &texture) { if (!texture.isValid()) { throw std::runtime_error("invalid backend texture"); @@ -203,7 +205,7 @@ class RNSkAndroidPlatformContext : public RNSkPlatformContext { throw std::runtime_error("couldn't get OpenGL texture"); } - OpenGLContext::getInstance().makeCurrent(); + getOpenGLContext().makeCurrent(); glFlush(); TextureInfo texInfo; @@ -229,6 +231,18 @@ class RNSkAndroidPlatformContext : public RNSkPlatformContext { private: JniPlatformContext *_jniPlatformContext; + +#if !defined(SK_GRAPHITE) + std::unique_ptr _openGLContext; + std::once_flag _openGLContextOnce; + + OpenGLContext &getOpenGLContext() { + std::call_once(_openGLContextOnce, [this]() { + _openGLContext = std::make_unique(); + }); + return *_openGLContext; + } +#endif }; } // namespace RNSkia diff --git a/packages/skia/android/cpp/rnskia-android/RNSkAndroidVideo.cpp b/packages/skia/android/cpp/rnskia-android/RNSkAndroidVideo.cpp index e4608b3eef..22b2536fb4 100644 --- a/packages/skia/android/cpp/rnskia-android/RNSkAndroidVideo.cpp +++ b/packages/skia/android/cpp/rnskia-android/RNSkAndroidVideo.cpp @@ -7,12 +7,6 @@ #include "RNSkLog.h" -#if defined(SK_GRAPHITE) -#include "RNDawnContext.h" -#else -#include "OpenGLContext.h" -#endif - #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -28,8 +22,9 @@ namespace RNSkia { namespace jsi = facebook::jsi; namespace jni = facebook::jni; -RNSkAndroidVideo::RNSkAndroidVideo(jni::global_ref jniVideo) - : _jniVideo(jniVideo) { +RNSkAndroidVideo::RNSkAndroidVideo(jni::global_ref jniVideo, + std::shared_ptr context) + : _jniVideo(jniVideo), _context(std::move(context)) { #if __ANDROID_API__ < 26 throw std::runtime_error("Skia Videos are only support on API 26 and above"); #endif @@ -59,11 +54,7 @@ sk_sp RNSkAndroidVideo::nextImage(double *timeStamp) { // Convert jobject to AHardwareBuffer AHardwareBuffer *buffer = AHardwareBuffer_fromHardwareBuffer(env, jHardwareBuffer); -#if defined(SK_GRAPHITE) - return DawnContext::getInstance().MakeImageFromBuffer(buffer); -#else - return OpenGLContext::getInstance().MakeImageFromBuffer(buffer); -#endif + return _context->makeImageFromNativeBuffer(buffer); #else return nullptr; #endif diff --git a/packages/skia/android/cpp/rnskia-android/RNSkAndroidVideo.h b/packages/skia/android/cpp/rnskia-android/RNSkAndroidVideo.h index dcf0c92d9a..fd814b9567 100644 --- a/packages/skia/android/cpp/rnskia-android/RNSkAndroidVideo.h +++ b/packages/skia/android/cpp/rnskia-android/RNSkAndroidVideo.h @@ -13,6 +13,7 @@ #pragma clang diagnostic pop +#include "RNSkPlatformContext.h" #include "RNSkVideo.h" namespace RNSkia { @@ -23,9 +24,11 @@ namespace jni = facebook::jni; class RNSkAndroidVideo : public RNSkVideo { private: jni::global_ref _jniVideo; + std::shared_ptr _context; public: - explicit RNSkAndroidVideo(jni::global_ref jniVideo); + explicit RNSkAndroidVideo(jni::global_ref jniVideo, + std::shared_ptr context); ~RNSkAndroidVideo() override; sk_sp nextImage(double *timeStamp = nullptr) override; double duration() override; diff --git a/packages/skia/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp b/packages/skia/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp index e8e4c0314b..3cb91c6dac 100644 --- a/packages/skia/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +++ b/packages/skia/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp @@ -7,12 +7,6 @@ #include "RNSkLog.h" -#if defined(SK_GRAPHITE) -#include "RNDawnContext.h" -#else -#include "OpenGLContext.h" -#endif - #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" @@ -107,11 +101,8 @@ void RNSkOpenGLCanvasProvider::surfaceAvailable(jobject jSurfaceTexture, } else { window = ANativeWindow_fromSurface(env, jSurfaceTexture); } -#if defined(SK_GRAPHITE) - _surfaceHolder = DawnContext::getInstance().MakeWindow(window, width, height); -#else - _surfaceHolder = OpenGLContext::getInstance().MakeWindow(window); -#endif + _surfaceHolder = + _platformContext->makeContextFromNativeSurface(window, width, height); // Post redraw request to ensure we paint in the next draw cycle. _requestRedraw(); @@ -145,4 +136,4 @@ void RNSkOpenGLCanvasProvider::surfaceSizeChanged(jobject jSurface, int width, // Redraw after size change _requestRedraw(); } -} // namespace RNSkia \ No newline at end of file +} // namespace RNSkia diff --git a/packages/skia/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h b/packages/skia/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h index ca5768de24..aee9222d9a 100644 --- a/packages/skia/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h +++ b/packages/skia/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.h @@ -34,7 +34,7 @@ class RNSkOpenGLCanvasProvider void surfaceSizeChanged(jobject jSurface, int width, int height, bool opaque); private: - std::unique_ptr _surfaceHolder = nullptr; + std::shared_ptr _surfaceHolder = nullptr; std::shared_ptr _platformContext; jobject _jSurfaceTexture = nullptr; jmethodID _updateTexImageMethod = nullptr; diff --git a/packages/skia/apple/MetalContext.h b/packages/skia/apple/MetalContext.h index 070f14d8a3..5391881d71 100644 --- a/packages/skia/apple/MetalContext.h +++ b/packages/skia/apple/MetalContext.h @@ -36,14 +36,10 @@ struct OffscreenRenderContext { class MetalContext { public: + MetalContext(); MetalContext(const MetalContext &) = delete; MetalContext &operator=(const MetalContext &) = delete; - static MetalContext &getInstance() { - static thread_local MetalContext instance; - return instance; - } - sk_sp MakeOffscreen(int width, int height) { auto device = _device; auto ctx = new OffscreenRenderContext(device, _directContext, _commandQueue, @@ -103,6 +99,4 @@ class MetalContext { id _device = nullptr; id _commandQueue = nullptr; sk_sp _directContext = nullptr; - - MetalContext(); }; diff --git a/packages/skia/apple/RNSkApplePlatformContext.h b/packages/skia/apple/RNSkApplePlatformContext.h index f7163cc036..2e765f865f 100644 --- a/packages/skia/apple/RNSkApplePlatformContext.h +++ b/packages/skia/apple/RNSkApplePlatformContext.h @@ -5,11 +5,16 @@ #include #include +#include #include #include "RNSkPlatformContext.h" #include "ViewScreenshotService.h" +#if !defined(SK_GRAPHITE) +#include "MetalContext.h" +#endif + namespace facebook { namespace react { class CallInvoker; @@ -22,20 +27,9 @@ class RNSkApplePlatformContext : public RNSkPlatformContext { public: RNSkApplePlatformContext( RCTBridge *bridge, - std::shared_ptr jsCallInvoker) -#if !TARGET_OS_OSX - : RNSkPlatformContext(jsCallInvoker, [[UIScreen mainScreen] scale]) { -#else - : RNSkPlatformContext(jsCallInvoker, - [[NSScreen mainScreen] backingScaleFactor]) { -#endif // !TARGET_OS_OSX - - // Create screenshot manager - _screenshotService = - [[ViewScreenshotService alloc] initWithUiManager:bridge.uiManager]; - } + std::shared_ptr jsCallInvoker); - ~RNSkApplePlatformContext() = default; + ~RNSkApplePlatformContext(); void runOnMainThread(std::function) override; @@ -62,7 +56,8 @@ class RNSkApplePlatformContext : public RNSkPlatformContext { std::shared_ptr createVideo(const std::string &url) override; std::shared_ptr - makeContextFromNativeSurface(void *surface, int width, int height) override; + makeContextFromNativeSurface(void *surface, int width, int height, + bool useP3ColorSpace = true) override; virtual void performStreamOperation( const std::string &sourceUri, @@ -80,6 +75,12 @@ class RNSkApplePlatformContext : public RNSkPlatformContext { private: ViewScreenshotService *_screenshotService; +#if !defined(SK_GRAPHITE) + MetalContext &metalContext(); + std::unique_ptr _metalContext; + std::once_flag _metalContextOnce; +#endif + SkColorType mtlPixelFormatToSkColorType(MTLPixelFormat pixelFormat); }; diff --git a/packages/skia/apple/RNSkApplePlatformContext.mm b/packages/skia/apple/RNSkApplePlatformContext.mm index 8bb0804d85..6f8fe38b5d 100644 --- a/packages/skia/apple/RNSkApplePlatformContext.mm +++ b/packages/skia/apple/RNSkApplePlatformContext.mm @@ -32,6 +32,31 @@ namespace RNSkia { +RNSkApplePlatformContext::RNSkApplePlatformContext( + RCTBridge *bridge, + std::shared_ptr jsCallInvoker) +#if !TARGET_OS_OSX + : RNSkPlatformContext(jsCallInvoker, [[UIScreen mainScreen] scale]) { +#else + : RNSkPlatformContext(jsCallInvoker, + [[NSScreen mainScreen] backingScaleFactor]) { +#endif // !TARGET_OS_OSX + // Create screenshot manager + _screenshotService = + [[ViewScreenshotService alloc] initWithUiManager:bridge.uiManager]; +} + +RNSkApplePlatformContext::~RNSkApplePlatformContext() = default; + +#if !defined(SK_GRAPHITE) +MetalContext &RNSkApplePlatformContext::metalContext() { + std::call_once(_metalContextOnce, [this]() { + _metalContext = std::make_unique(); + }); + return *_metalContext; +} +#endif + void RNSkApplePlatformContext::performStreamOperation( const std::string &sourceUri, const std::function)> &op) { @@ -172,7 +197,7 @@ #if !defined(SK_GRAPHITE) GrDirectContext *RNSkApplePlatformContext::getDirectContext() { - return MetalContext::getInstance().getDirectContext(); + return metalContext().getDirectContext(); } const TextureInfo RNSkApplePlatformContext::getTexture(sk_sp image) { @@ -238,12 +263,13 @@ std::shared_ptr RNSkApplePlatformContext::makeContextFromNativeSurface(void *surface, int width, - int height) { + int height, + bool useP3ColorSpace) { #if defined(SK_GRAPHITE) return DawnContext::getInstance().MakeWindow(surface, width, height); #else - return MetalContext::getInstance().MakeWindow((__bridge CALayer *)surface, - width, height); + return metalContext().MakeWindow((__bridge CALayer *)surface, width, height, + useP3ColorSpace); #endif } @@ -256,7 +282,7 @@ #if defined(SK_GRAPHITE) return DawnContext::getInstance().MakeOffscreen(width, height); #else - return MetalContext::getInstance().MakeOffscreen(width, height); + return metalContext().MakeOffscreen(width, height); #endif } @@ -265,7 +291,7 @@ #if defined(SK_GRAPHITE) return DawnContext::getInstance().MakeImageFromBuffer(buffer); #else - return MetalContext::getInstance().MakeImageFromBuffer(buffer); + return metalContext().MakeImageFromBuffer(buffer); #endif } diff --git a/packages/skia/apple/RNSkMetalCanvasProvider.h b/packages/skia/apple/RNSkMetalCanvasProvider.h index 205e7ad99d..54a3f2d0be 100644 --- a/packages/skia/apple/RNSkMetalCanvasProvider.h +++ b/packages/skia/apple/RNSkMetalCanvasProvider.h @@ -32,7 +32,7 @@ class RNSkMetalCanvasProvider : public RNSkia::RNSkCanvasProvider { private: std::shared_ptr _context; - std::unique_ptr _ctx = nullptr; + std::shared_ptr _ctx = nullptr; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunguarded-availability-new" CAMetalLayer *_layer; diff --git a/packages/skia/apple/RNSkMetalCanvasProvider.mm b/packages/skia/apple/RNSkMetalCanvasProvider.mm index cc5007733e..222acab52f 100644 --- a/packages/skia/apple/RNSkMetalCanvasProvider.mm +++ b/packages/skia/apple/RNSkMetalCanvasProvider.mm @@ -4,8 +4,6 @@ #if defined(SK_GRAPHITE) #import "RNDawnContext.h" -#else -#import "MetalContext.h" #endif #pragma clang diagnostic push @@ -98,7 +96,8 @@ _ctx = RNSkia::DawnContext::getInstance().MakeWindow((__bridge void *)_layer, w, h); #else - _ctx = MetalContext::getInstance().MakeWindow(_layer, w, h, _useP3ColorSpace); + _ctx = _context->makeContextFromNativeSurface((__bridge void *)_layer, w, h, + _useP3ColorSpace); #endif _requestRedraw(); } diff --git a/packages/skia/apple/SkiaCVPixelBufferUtils.mm b/packages/skia/apple/SkiaCVPixelBufferUtils.mm index eaf202e3d1..c49812d0d7 100644 --- a/packages/skia/apple/SkiaCVPixelBufferUtils.mm +++ b/packages/skia/apple/SkiaCVPixelBufferUtils.mm @@ -31,16 +31,12 @@ #include #if TARGET_RT_BIG_ENDIAN #define FourCC2Str(fourcc) \ - (const char[]) { \ - *((char *)&fourcc), *(((char *)&fourcc) + 1), *(((char *)&fourcc) + 2), \ - *(((char *)&fourcc) + 3), 0 \ - } + (const char[]){*((char *)&fourcc), *(((char *)&fourcc) + 1), \ + *(((char *)&fourcc) + 2), *(((char *)&fourcc) + 3), 0} #else #define FourCC2Str(fourcc) \ - (const char[]) { \ - *(((char *)&fourcc) + 3), *(((char *)&fourcc) + 2), \ - *(((char *)&fourcc) + 1), *(((char *)&fourcc) + 0), 0 \ - } + (const char[]){*(((char *)&fourcc) + 3), *(((char *)&fourcc) + 2), \ + *(((char *)&fourcc) + 1), *(((char *)&fourcc) + 0), 0} #endif // pragma MARK: TextureHolder diff --git a/packages/skia/cpp/rnskia/RNSkPlatformContext.h b/packages/skia/cpp/rnskia/RNSkPlatformContext.h index 076d59d28d..5f8ebaaf54 100644 --- a/packages/skia/cpp/rnskia/RNSkPlatformContext.h +++ b/packages/skia/cpp/rnskia/RNSkPlatformContext.h @@ -38,7 +38,8 @@ struct TextureInfo { bool glProtected = false; }; -class RNSkPlatformContext { +class RNSkPlatformContext + : public std::enable_shared_from_this { public: /** * Constructor @@ -95,7 +96,8 @@ class RNSkPlatformContext { virtual sk_sp makeOffscreenSurface(int width, int height) = 0; virtual std::shared_ptr - makeContextFromNativeSurface(void *surface, int width, int height) = 0; + makeContextFromNativeSurface(void *surface, int width, int height, + bool useP3ColorSpace = true) = 0; /** * Creates an image from a native buffer.