@shopify/react-native-skia 1.6.0 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/android/cpp/jni/include/JniSkiaBaseView.h +2 -3
  2. package/android/cpp/jni/include/JniSkiaManager.h +2 -2
  3. package/android/cpp/rnskia-android/GrAHardwareBufferUtils.cpp +14 -14
  4. package/android/cpp/rnskia-android/MainThreadDispatcher.h +4 -6
  5. package/android/cpp/rnskia-android/OpenGLContext.h +24 -10
  6. package/android/cpp/rnskia-android/OpenGLWindowContext.h +3 -3
  7. package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +64 -8
  8. package/android/cpp/rnskia-android/RNSkAndroidVideo.cpp +1 -1
  9. package/android/cpp/rnskia-android/RNSkAndroidVideo.h +1 -1
  10. package/android/cpp/rnskia-android/RNSkAndroidView.h +0 -4
  11. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +3 -3
  12. package/android/cpp/rnskia-android/gl/Display.h +2 -0
  13. package/cpp/api/JsiSkApi.h +1 -1
  14. package/cpp/api/JsiSkCanvas.h +1 -1
  15. package/cpp/api/JsiSkColor.h +2 -2
  16. package/cpp/api/JsiSkContourMeasure.h +1 -5
  17. package/cpp/api/JsiSkImage.h +11 -0
  18. package/cpp/api/JsiSkImageFactory.h +14 -0
  19. package/cpp/api/JsiSkPicture.h +2 -0
  20. package/cpp/api/JsiSkSurface.h +7 -0
  21. package/cpp/api/JsiTextureInfo.h +53 -0
  22. package/cpp/api/third_party/CSSColorParser.h +1 -1
  23. package/cpp/api/third_party/base64.cpp +4 -4
  24. package/cpp/jsi/ViewProperty.h +48 -0
  25. package/cpp/rnskia/RNSkDomView.h +4 -7
  26. package/cpp/rnskia/RNSkJsiViewApi.h +3 -3
  27. package/cpp/rnskia/RNSkManager.cpp +1 -1
  28. package/cpp/rnskia/RNSkPictureView.h +8 -18
  29. package/cpp/rnskia/RNSkPlatformContext.h +18 -13
  30. package/cpp/rnskia/RNSkView.h +2 -8
  31. package/ios/RNSkia-iOS/MetalContext.h +101 -15
  32. package/ios/RNSkia-iOS/MetalContext.mm +9 -8
  33. package/ios/RNSkia-iOS/MetalWindowContext.h +39 -0
  34. package/ios/RNSkia-iOS/MetalWindowContext.mm +60 -0
  35. package/ios/RNSkia-iOS/RNSkiOSPlatformContext.h +13 -29
  36. package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +88 -2
  37. package/ios/RNSkia-iOS/SkiaCVPixelBufferUtils.mm +17 -6
  38. package/ios/RNSkia-iOS/SkiaDomView.mm +3 -3
  39. package/ios/RNSkia-iOS/SkiaDomViewManager.mm +2 -1
  40. package/ios/RNSkia-iOS/SkiaManager.h +6 -0
  41. package/ios/RNSkia-iOS/SkiaManager.mm +18 -2
  42. package/ios/RNSkia-iOS/SkiaPictureView.mm +3 -3
  43. package/ios/RNSkia-iOS/SkiaPictureViewManager.mm +2 -1
  44. package/ios/RNSkia-iOS/SkiaUIView.h +0 -1
  45. package/ios/RNSkia-iOS/SkiaUIView.mm +18 -22
  46. package/lib/commonjs/skia/types/Image/Image.d.ts +10 -0
  47. package/lib/commonjs/skia/types/Image/Image.js.map +1 -1
  48. package/lib/commonjs/skia/types/Image/ImageFactory.d.ts +18 -0
  49. package/lib/commonjs/skia/types/Image/ImageFactory.js.map +1 -1
  50. package/lib/commonjs/skia/types/Matrix4.d.ts +6 -0
  51. package/lib/commonjs/skia/types/Matrix4.js +69 -1
  52. package/lib/commonjs/skia/types/Matrix4.js.map +1 -1
  53. package/lib/commonjs/skia/types/Surface/Surface.d.ts +11 -0
  54. package/lib/commonjs/skia/types/Surface/Surface.js.map +1 -1
  55. package/lib/commonjs/skia/web/JsiSkImage.d.ts +1 -0
  56. package/lib/commonjs/skia/web/JsiSkImage.js +4 -0
  57. package/lib/commonjs/skia/web/JsiSkImage.js.map +1 -1
  58. package/lib/commonjs/skia/web/JsiSkImageFactory.d.ts +1 -0
  59. package/lib/commonjs/skia/web/JsiSkImageFactory.js +3 -0
  60. package/lib/commonjs/skia/web/JsiSkImageFactory.js.map +1 -1
  61. package/lib/commonjs/skia/web/JsiSkSurface.d.ts +1 -0
  62. package/lib/commonjs/skia/web/JsiSkSurface.js +4 -0
  63. package/lib/commonjs/skia/web/JsiSkSurface.js.map +1 -1
  64. package/lib/module/skia/types/Image/Image.d.ts +10 -0
  65. package/lib/module/skia/types/Image/Image.js.map +1 -1
  66. package/lib/module/skia/types/Image/ImageFactory.d.ts +18 -0
  67. package/lib/module/skia/types/Image/ImageFactory.js.map +1 -1
  68. package/lib/module/skia/types/Matrix4.d.ts +6 -0
  69. package/lib/module/skia/types/Matrix4.js +67 -0
  70. package/lib/module/skia/types/Matrix4.js.map +1 -1
  71. package/lib/module/skia/types/Surface/Surface.d.ts +11 -0
  72. package/lib/module/skia/types/Surface/Surface.js.map +1 -1
  73. package/lib/module/skia/web/JsiSkImage.d.ts +1 -0
  74. package/lib/module/skia/web/JsiSkImage.js +4 -0
  75. package/lib/module/skia/web/JsiSkImage.js.map +1 -1
  76. package/lib/module/skia/web/JsiSkImageFactory.d.ts +1 -0
  77. package/lib/module/skia/web/JsiSkImageFactory.js +3 -0
  78. package/lib/module/skia/web/JsiSkImageFactory.js.map +1 -1
  79. package/lib/module/skia/web/JsiSkSurface.d.ts +1 -0
  80. package/lib/module/skia/web/JsiSkSurface.js +4 -0
  81. package/lib/module/skia/web/JsiSkSurface.js.map +1 -1
  82. package/lib/typescript/lib/commonjs/skia/types/Matrix4.d.ts +6 -0
  83. package/lib/typescript/lib/commonjs/skia/web/JsiSkImage.d.ts +1 -0
  84. package/lib/typescript/lib/commonjs/skia/web/JsiSkImageFactory.d.ts +1 -0
  85. package/lib/typescript/lib/commonjs/skia/web/JsiSkSurface.d.ts +1 -0
  86. package/lib/typescript/lib/module/mock/index.d.ts +1 -0
  87. package/lib/typescript/lib/module/skia/types/Matrix4.d.ts +1 -0
  88. package/lib/typescript/lib/module/skia/web/JsiSkImage.d.ts +1 -0
  89. package/lib/typescript/lib/module/skia/web/JsiSkImageFactory.d.ts +1 -0
  90. package/lib/typescript/lib/module/skia/web/JsiSkSurface.d.ts +1 -0
  91. package/lib/typescript/src/skia/types/Image/Image.d.ts +10 -0
  92. package/lib/typescript/src/skia/types/Image/ImageFactory.d.ts +18 -0
  93. package/lib/typescript/src/skia/types/Matrix4.d.ts +6 -0
  94. package/lib/typescript/src/skia/types/Surface/Surface.d.ts +11 -0
  95. package/lib/typescript/src/skia/web/JsiSkImage.d.ts +1 -0
  96. package/lib/typescript/src/skia/web/JsiSkImageFactory.d.ts +1 -0
  97. package/lib/typescript/src/skia/web/JsiSkSurface.d.ts +1 -0
  98. package/package.json +1 -1
  99. package/src/renderer/__tests__/e2e/Matrix4.spec.tsx +93 -0
  100. package/src/skia/types/Image/Image.ts +11 -0
  101. package/src/skia/types/Image/ImageFactory.ts +24 -0
  102. package/src/skia/types/Matrix4.ts +101 -0
  103. package/src/skia/types/Surface/Surface.ts +12 -0
  104. package/src/skia/web/JsiSkImage.ts +5 -0
  105. package/src/skia/web/JsiSkImageFactory.ts +4 -0
  106. package/src/skia/web/JsiSkSurface.ts +5 -0
  107. package/cpp/jsi/JsiValueWrapper.h +0 -164
  108. package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h +0 -128
  109. package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm +0 -92
@@ -1,6 +1,7 @@
1
1
  #import "RNSkiOSPlatformContext.h"
2
2
 
3
3
  #import <CoreMedia/CMSampleBuffer.h>
4
+ #include <Metal/Metal.h>
4
5
  #import <React/RCTUtils.h>
5
6
  #include <thread>
6
7
  #include <utility>
@@ -81,8 +82,8 @@ uint64_t RNSkiOSPlatformContext::makeNativeBuffer(sk_sp<SkImage> image) {
81
82
  #else
82
83
  // on iOS, 32_BGRA is the only supported RGB format for CVPixelBuffers.
83
84
  image = image->makeColorTypeAndColorSpace(
84
- MetalContext::getInstance()._context.skContext.get(),
85
- kBGRA_8888_SkColorType, SkColorSpace::MakeSRGB());
85
+ MetalContext::getInstance().getDirectContext(), kBGRA_8888_SkColorType,
86
+ SkColorSpace::MakeSRGB());
86
87
  #endif
87
88
  if (image == nullptr) {
88
89
  throw std::runtime_error(
@@ -155,6 +156,38 @@ uint64_t RNSkiOSPlatformContext::makeNativeBuffer(sk_sp<SkImage> image) {
155
156
  return reinterpret_cast<uint64_t>(pixelBuffer);
156
157
  }
157
158
 
159
+ const TextureInfo RNSkiOSPlatformContext::getTexture(sk_sp<SkImage> image) {
160
+ GrBackendTexture texture;
161
+ TextureInfo result;
162
+ if (!SkImages::GetBackendTextureFromImage(image, &texture, true)) {
163
+ throw std::runtime_error("Couldn't get backend texture");
164
+ }
165
+ if (!texture.isValid()) {
166
+ throw std::runtime_error("Invalid backend texture");
167
+ }
168
+ GrMtlTextureInfo textureInfo;
169
+ if (!GrBackendTextures::GetMtlTextureInfo(texture, &textureInfo)) {
170
+ throw std::runtime_error("Couldn't get Metal texture info");
171
+ }
172
+ result.mtlTexture = textureInfo.fTexture.get();
173
+ return result;
174
+ }
175
+
176
+ const TextureInfo RNSkiOSPlatformContext::getTexture(sk_sp<SkSurface> surface) {
177
+ GrBackendTexture texture = SkSurfaces::GetBackendTexture(
178
+ surface.get(), SkSurfaces::BackendHandleAccess::kFlushRead);
179
+ TextureInfo result;
180
+ if (!texture.isValid()) {
181
+ throw std::runtime_error("Invalid backend texture");
182
+ }
183
+ GrMtlTextureInfo textureInfo;
184
+ if (!GrBackendTextures::GetMtlTextureInfo(texture, &textureInfo)) {
185
+ throw std::runtime_error("Couldn't get Metal texture info");
186
+ }
187
+ result.mtlTexture = textureInfo.fTexture.get();
188
+ return result;
189
+ }
190
+
158
191
  std::shared_ptr<RNSkVideo>
159
192
  RNSkiOSPlatformContext::createVideo(const std::string &url) {
160
193
  return std::make_shared<RNSkiOSVideo>(url, this);
@@ -192,6 +225,59 @@ sk_sp<SkImage> RNSkiOSPlatformContext::makeImageFromNativeBuffer(void *buffer) {
192
225
  #endif
193
226
  }
194
227
 
228
+ sk_sp<SkImage> RNSkiOSPlatformContext::makeImageFromNativeTexture(
229
+ const TextureInfo &texInfo, int width, int height, bool mipMapped) {
230
+ id<MTLTexture> mtlTexture = (__bridge id<MTLTexture>)(texInfo.mtlTexture);
231
+
232
+ SkColorType colorType = mtlPixelFormatToSkColorType(mtlTexture.pixelFormat);
233
+ if (colorType == SkColorType::kUnknown_SkColorType) {
234
+ throw std::runtime_error("Unsupported pixelFormat");
235
+ }
236
+
237
+ GrMtlTextureInfo textureInfo;
238
+ textureInfo.fTexture.retain((__bridge const void *)mtlTexture);
239
+
240
+ GrBackendTexture texture = GrBackendTextures::MakeMtl(
241
+ width, height, mipMapped ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo,
242
+ textureInfo);
243
+
244
+ return SkImages::BorrowTextureFrom(getDirectContext(), texture,
245
+ kTopLeft_GrSurfaceOrigin, colorType,
246
+ kPremul_SkAlphaType, nullptr);
247
+ }
248
+
249
+ SkColorType RNSkiOSPlatformContext::mtlPixelFormatToSkColorType(
250
+ MTLPixelFormat pixelFormat) {
251
+ switch (pixelFormat) {
252
+ case MTLPixelFormatRGBA8Unorm:
253
+ return kRGBA_8888_SkColorType;
254
+ case MTLPixelFormatBGRA8Unorm:
255
+ return kBGRA_8888_SkColorType;
256
+ case MTLPixelFormatRGB10A2Unorm:
257
+ return kRGBA_1010102_SkColorType;
258
+ case MTLPixelFormatR8Unorm:
259
+ return kGray_8_SkColorType;
260
+ case MTLPixelFormatRGBA16Float:
261
+ return kRGBA_F16_SkColorType;
262
+ case MTLPixelFormatRG8Unorm:
263
+ return kR8G8_unorm_SkColorType;
264
+ case MTLPixelFormatR16Float:
265
+ return kA16_float_SkColorType;
266
+ case MTLPixelFormatRG16Float:
267
+ return kR16G16_float_SkColorType;
268
+ case MTLPixelFormatR16Unorm:
269
+ return kA16_unorm_SkColorType;
270
+ case MTLPixelFormatRG16Unorm:
271
+ return kR16G16_unorm_SkColorType;
272
+ case MTLPixelFormatRGBA16Unorm:
273
+ return kR16G16B16A16_unorm_SkColorType;
274
+ case MTLPixelFormatRGBA8Unorm_sRGB:
275
+ return kSRGBA_8888_SkColorType;
276
+ default:
277
+ return kUnknown_SkColorType;
278
+ }
279
+ }
280
+
195
281
  #if !defined(SK_GRAPHITE)
196
282
  GrDirectContext *RNSkiOSPlatformContext::getDirectContext() {
197
283
  return MetalContext::getInstance().getDirectContext();
@@ -6,29 +6,40 @@
6
6
  //
7
7
 
8
8
  #import "SkiaCVPixelBufferUtils.h"
9
- #import "SkiaMetalSurfaceFactory.h"
10
9
 
11
10
  #pragma clang diagnostic push
12
11
  #pragma clang diagnostic ignored "-Wdocumentation"
12
+
13
+ #import "include/core/SkCanvas.h"
13
14
  #import "include/core/SkColorSpace.h"
15
+
16
+ #import <CoreMedia/CMSampleBuffer.h>
17
+ #import <CoreVideo/CVMetalTextureCache.h>
18
+
14
19
  #import <include/gpu/ganesh/GrBackendSurface.h>
20
+ #import <include/gpu/ganesh/GrDirectContext.h>
15
21
  #import <include/gpu/ganesh/SkImageGanesh.h>
22
+ #import <include/gpu/ganesh/SkSurfaceGanesh.h>
16
23
  #import <include/gpu/ganesh/mtl/GrMtlBackendContext.h>
17
24
  #import <include/gpu/ganesh/mtl/GrMtlBackendSurface.h>
18
25
  #import <include/gpu/ganesh/mtl/GrMtlDirectContext.h>
19
- #import <include/gpu/ganesh/mtl/GrMtlTypes.h>
20
26
  #import <include/gpu/ganesh/mtl/SkSurfaceMetal.h>
27
+
21
28
  #pragma clang diagnostic pop
22
29
 
23
30
  #include <TargetConditionals.h>
24
31
  #if TARGET_RT_BIG_ENDIAN
25
32
  #define FourCC2Str(fourcc) \
26
- (const char[]){*((char *)&fourcc), *(((char *)&fourcc) + 1), \
27
- *(((char *)&fourcc) + 2), *(((char *)&fourcc) + 3), 0}
33
+ (const char[]) { \
34
+ *((char *)&fourcc), *(((char *)&fourcc) + 1), *(((char *)&fourcc) + 2), \
35
+ *(((char *)&fourcc) + 3), 0 \
36
+ }
28
37
  #else
29
38
  #define FourCC2Str(fourcc) \
30
- (const char[]){*(((char *)&fourcc) + 3), *(((char *)&fourcc) + 2), \
31
- *(((char *)&fourcc) + 1), *(((char *)&fourcc) + 0), 0}
39
+ (const char[]) { \
40
+ *(((char *)&fourcc) + 3), *(((char *)&fourcc) + 2), \
41
+ *(((char *)&fourcc) + 1), *(((char *)&fourcc) + 0), 0 \
42
+ }
32
43
  #endif
33
44
 
34
45
  // pragma MARK: TextureHolder
@@ -24,10 +24,10 @@ using namespace facebook::react;
24
24
 
25
25
  - (instancetype)initWithFrame:(CGRect)frame {
26
26
  if (self = [super initWithFrame:frame]) {
27
- auto skManager = [[self skiaManager] skManager];
28
- // Pass SkManager as a raw pointer to avoid circular dependenciesr
27
+ // Pass SkManager as a raw pointer to avoid circular dependencies
28
+ auto skManager = [SkiaManager latestActiveSkManager].get();
29
29
  [self
30
- initCommon:skManager.get()
30
+ initCommon:skManager
31
31
  factory:[](std::shared_ptr<RNSkia::RNSkPlatformContext> context) {
32
32
  return std::make_shared<RNSkiOSView<RNSkia::RNSkDomView>>(context);
33
33
  }];
@@ -15,7 +15,8 @@
15
15
  RCT_EXPORT_MODULE(SkiaDomView)
16
16
 
17
17
  - (SkiaManager *)skiaManager {
18
- auto bridge = [RCTBridge currentBridge];
18
+ auto bridge = self.bridge;
19
+ RCTAssert(bridge, @"Bridge must not be nil.");
19
20
  auto skiaModule = (RNSkiaModule *)[bridge moduleForName:@"RNSkiaModule"];
20
21
  return [skiaModule manager];
21
22
  }
@@ -16,4 +16,10 @@
16
16
  jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)
17
17
  jsInvoker;
18
18
 
19
+ #ifdef RCT_NEW_ARCH_ENABLED
20
+ // Fabric components do not have a better way to interact with TurboModules.
21
+ // Workaround to get the SkManager instance from singleton.
22
+ + (std::shared_ptr<RNSkia::RNSkManager>)latestActiveSkManager;
23
+ #endif // RCT_NEW_ARCH_ENABLED
24
+
19
25
  @end
@@ -8,6 +8,8 @@
8
8
 
9
9
  #import "RNSkiOSPlatformContext.h"
10
10
 
11
+ static __weak SkiaManager *sharedInstance = nil;
12
+
11
13
  @implementation SkiaManager {
12
14
  std::shared_ptr<RNSkia::RNSkManager> _skManager;
13
15
  __weak RCTBridge *weakBridge;
@@ -29,6 +31,7 @@
29
31
  jsInvoker {
30
32
  self = [super init];
31
33
  if (self) {
34
+ sharedInstance = self;
32
35
  RCTCxxBridge *cxxBridge = (RCTCxxBridge *)bridge;
33
36
  if (cxxBridge.runtime) {
34
37
 
@@ -38,11 +41,24 @@
38
41
  // Create the RNSkiaManager (cross platform)
39
42
  _skManager = std::make_shared<RNSkia::RNSkManager>(
40
43
  jsRuntime, jsInvoker,
41
- std::make_shared<RNSkia::RNSkiOSPlatformContext>(jsRuntime, bridge,
42
- jsInvoker));
44
+ std::make_shared<RNSkia::RNSkiOSPlatformContext>(bridge, jsInvoker));
43
45
  }
44
46
  }
45
47
  return self;
46
48
  }
47
49
 
50
+ - (void)dealloc
51
+ {
52
+ sharedInstance = nil;
53
+ }
54
+
55
+ #ifdef RCT_NEW_ARCH_ENABLED
56
+ + (std::shared_ptr<RNSkia::RNSkManager>)latestActiveSkManager
57
+ {
58
+ if (sharedInstance != nil) {
59
+ return [sharedInstance skManager];
60
+ }
61
+ return nullptr;
62
+ }
63
+ #endif // RCT_NEW_ARCH_ENABLED
48
64
  @end
@@ -24,9 +24,9 @@ using namespace facebook::react;
24
24
 
25
25
  - (instancetype)initWithFrame:(CGRect)frame {
26
26
  if (self = [super initWithFrame:frame]) {
27
- auto skManager = [[self skiaManager] skManager];
28
- // Pass SkManager as a raw pointer to avoid circular dependenciesr
29
- [self initCommon:skManager.get()
27
+ // Pass SkManager as a raw pointer to avoid circular dependencies
28
+ auto skManager = [SkiaManager latestActiveSkManager].get();
29
+ [self initCommon:skManager
30
30
  factory:[](std::shared_ptr<RNSkia::RNSkPlatformContext> context) {
31
31
  return std::make_shared<RNSkiOSView<RNSkia::RNSkPictureView>>(
32
32
  context);
@@ -15,7 +15,8 @@
15
15
  RCT_EXPORT_MODULE(SkiaPictureView)
16
16
 
17
17
  - (SkiaManager *)skiaManager {
18
- auto bridge = [RCTBridge currentBridge];
18
+ auto bridge = self.bridge;
19
+ RCTAssert(bridge, @"Bridge must not be nil.");
19
20
  auto skiaModule = (RNSkiaModule *)[bridge moduleForName:@"RNSkiaModule"];
20
21
  return [skiaModule manager];
21
22
  }
@@ -29,7 +29,6 @@
29
29
  factory:(std::function<std::shared_ptr<RNSkBaseiOSView>(
30
30
  std::shared_ptr<RNSkia::RNSkPlatformContext>)>)factory;
31
31
  - (std::shared_ptr<RNSkBaseiOSView>)impl;
32
- - (SkiaManager *)skiaManager;
33
32
 
34
33
  - (void)setDebugMode:(bool)debugMode;
35
34
  - (void)setOpaque:(bool)opaque;
@@ -48,12 +48,6 @@
48
48
  _factory = factory;
49
49
  }
50
50
 
51
- - (SkiaManager *)skiaManager {
52
- auto bridge = [RCTBridge currentBridge];
53
- auto skiaModule = (RNSkiaModule *)[bridge moduleForName:@"RNSkiaModule"];
54
- return [skiaModule manager];
55
- }
56
-
57
51
  - (void)willInvalidateModules {
58
52
  _impl = nullptr;
59
53
  _manager = nullptr;
@@ -62,18 +56,7 @@
62
56
  #pragma mark Lifecycle
63
57
 
64
58
  - (void)willMoveToSuperview:(UIView *)newWindow {
65
- if (newWindow == NULL) {
66
- // Remove implementation view when the parent view is not set
67
- if (_impl != nullptr) {
68
- [_impl->getLayer() removeFromSuperlayer];
69
-
70
- if (_nativeId != 0 && _manager != nullptr) {
71
- _manager->setSkiaView(_nativeId, nullptr);
72
- }
73
-
74
- _impl = nullptr;
75
- }
76
- } else {
59
+ if (newWindow != nullptr) {
77
60
  // Create implementation view when the parent view is set
78
61
  if (_impl == nullptr && _manager != nullptr) {
79
62
  _impl = _factory(_manager->getPlatformContext());
@@ -90,6 +73,21 @@
90
73
  }
91
74
  }
92
75
 
76
+ - (void)removeFromSuperview {
77
+ // Cleanup when removed from view hierarchy
78
+ if (_impl != nullptr) {
79
+ [_impl->getLayer() removeFromSuperlayer];
80
+
81
+ if (_nativeId != 0 && _manager != nullptr) {
82
+ _manager->setSkiaView(_nativeId, nullptr);
83
+ }
84
+
85
+ _impl = nullptr;
86
+ }
87
+
88
+ [super removeFromSuperview];
89
+ }
90
+
93
91
  - (void)dealloc {
94
92
  [self unregisterView];
95
93
  [[NSNotificationCenter defaultCenter]
@@ -110,7 +108,7 @@
110
108
  // this flag is only set when the view is inserted and we want to set the
111
109
  // manager here since the view could be recycled or the app could be
112
110
  // refreshed and we would have a stale manager then
113
- _manager = [[self skiaManager] skManager].get();
111
+ _manager = [SkiaManager latestActiveSkManager].get();
114
112
  }
115
113
  }
116
114
  #endif // RCT_NEW_ARCH_ENABLED
@@ -119,8 +117,6 @@
119
117
  if (_manager != nullptr && _nativeId != 0) {
120
118
  _manager->unregisterSkiaView(_nativeId);
121
119
  }
122
-
123
- assert(_impl == nullptr);
124
120
  }
125
121
 
126
122
  #pragma Render
@@ -152,7 +148,7 @@
152
148
  }
153
149
 
154
150
  - (void)setOpaque:(bool)opaque {
155
- _opaque = opaque;
151
+ _opaque = opaque;
156
152
  }
157
153
 
158
154
  - (void)setNativeId:(size_t)nativeId {
@@ -38,6 +38,16 @@ export interface SkImage extends SkJSIInstance<"Image"> {
38
38
  * Returns the ImageInfo describing the image.
39
39
  */
40
40
  getImageInfo(): ImageInfo;
41
+ /**
42
+ * Returns the backend texture of the image.
43
+ * The returned object can be used to create a Skia Image object.
44
+ * The returned object is backend specific and should be used with caution.
45
+ * It is the caller's responsibility to ensure that the texture is not used after the image is deleted.
46
+ * The returned object may be null if the image does not have a backend texture.
47
+ *
48
+ * @return backend texture of the image or null
49
+ */
50
+ getNativeTextureUnstable(): unknown;
41
51
  /**
42
52
  * Returns this image as a shader with the specified tiling. It will use cubic sampling.
43
53
  * @param tx - tile mode in the x direction.
@@ -1 +1 @@
1
- {"version":3,"names":["FilterMode","exports","MipmapMode","ImageFormat"],"sources":["Image.ts"],"sourcesContent":["import type { SkMatrix } from \"../Matrix\";\nimport type { SkJSIInstance } from \"../JsiInstance\";\nimport type { TileMode } from \"../ImageFilter\";\nimport type { SkShader } from \"../Shader\";\n\nimport type { ImageInfo } from \"./ImageFactory\";\n\nexport interface CubicResampler {\n B: number;\n C: number;\n}\n\nexport interface FilterOptions {\n filter: FilterMode;\n mipmap?: MipmapMode;\n}\n\nexport enum FilterMode {\n Nearest,\n Linear,\n}\n\nexport enum MipmapMode {\n None,\n Nearest,\n Linear,\n}\n\nexport enum ImageFormat {\n JPEG = 3,\n PNG = 4,\n WEBP = 6,\n}\n\nexport interface SkImage extends SkJSIInstance<\"Image\"> {\n /**\n * Returns the possibly scaled height of the image.\n */\n height(): number;\n\n /**\n * Returns the possibly scaled width of the image.\n */\n width(): number;\n\n /**\n * Returns the ImageInfo describing the image.\n */\n getImageInfo(): ImageInfo;\n\n /**\n * Returns this image as a shader with the specified tiling. It will use cubic sampling.\n * @param tx - tile mode in the x direction.\n * @param ty - tile mode in the y direction.\n * @param fm - The filter mode. (default nearest)\n * @param mm - The mipmap mode. Note: for settings other than None, the image must have mipmaps (default none)\n * calculated with makeCopyWithDefaultMipmaps;\n * @param localMatrix\n */\n makeShaderOptions(\n tx: TileMode,\n ty: TileMode,\n fm: FilterMode,\n mm: MipmapMode,\n localMatrix?: SkMatrix\n ): SkShader;\n\n /**\n * Returns this image as a shader with the specified tiling. It will use cubic sampling.\n * @param tx - tile mode in the x direction.\n * @param ty - tile mode in the y direction.\n * @param B - See CubicResampler in SkSamplingOptions.h for more information\n * @param C - See CubicResampler in SkSamplingOptions.h for more information\n * @param localMatrix\n */\n makeShaderCubic(\n tx: TileMode,\n ty: TileMode,\n B: number,\n C: number,\n localMatrix?: SkMatrix\n ): SkShader;\n\n /** Encodes Image pixels, returning result as UInt8Array. Returns existing\n encoded data if present; otherwise, SkImage is encoded with\n SkEncodedImageFormat::kPNG. Skia must be built with SK_ENCODE_PNG to encode\n SkImage.\n\n Returns nullptr if existing encoded data is missing or invalid, and\n encoding fails.\n\n @param fmt - PNG is the default value.\n @param quality - a value from 0 to 100; 100 is the least lossy. May be ignored.\n\n @return Uint8Array with data\n */\n encodeToBytes(fmt?: ImageFormat, quality?: number): Uint8Array;\n\n /** Encodes Image pixels, returning result as a base64 encoded string. Returns existing\n encoded data if present; otherwise, SkImage is encoded with\n SkEncodedImageFormat::kPNG. Skia must be built with SK_ENCODE_PNG to encode\n SkImage.\n\n Returns nullptr if existing encoded data is missing or invalid, and\n encoding fails.\n\n @param fmt - PNG is the default value.\n @param quality - a value from 0 to 100; 100 is the least lossy. May be ignored.\n\n @return base64 encoded string of data\n */\n encodeToBase64(fmt?: ImageFormat, quality?: number): string;\n\n /** Read Image pixels\n *\n * @param srcX - optional x-axis upper left corner of the rectangle to read from\n * @param srcY - optional y-axis upper left corner of the rectangle to read from\n * @param imageInfo - optional describes the pixel format and dimensions of the data to read into\n * @return Float32Array or Uint8Array with data or null if the read failed.\n */\n readPixels(\n srcX?: number,\n srcY?: number,\n imageInfo?: ImageInfo\n ): Float32Array | Uint8Array | null;\n\n /**\n * Returns raster image or lazy image. Copies SkImage backed by GPU texture\n * into CPU memory if needed. Returns original SkImage if decoded in raster\n * bitmap, or if encoded in a stream.\n */\n makeNonTextureImage(): SkImage;\n}\n"],"mappings":";;;;;;IAiBYA,UAAU,GAAAC,OAAA,CAAAD,UAAA,0BAAVA,UAAU;EAAVA,UAAU,CAAVA,UAAU;EAAVA,UAAU,CAAVA,UAAU;EAAA,OAAVA,UAAU;AAAA;AAAA,IAKVE,UAAU,GAAAD,OAAA,CAAAC,UAAA,0BAAVA,UAAU;EAAVA,UAAU,CAAVA,UAAU;EAAVA,UAAU,CAAVA,UAAU;EAAVA,UAAU,CAAVA,UAAU;EAAA,OAAVA,UAAU;AAAA;AAAA,IAMVC,WAAW,GAAAF,OAAA,CAAAE,WAAA,0BAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAA,OAAXA,WAAW;AAAA","ignoreList":[]}
1
+ {"version":3,"names":["FilterMode","exports","MipmapMode","ImageFormat"],"sources":["Image.ts"],"sourcesContent":["import type { SkMatrix } from \"../Matrix\";\nimport type { SkJSIInstance } from \"../JsiInstance\";\nimport type { TileMode } from \"../ImageFilter\";\nimport type { SkShader } from \"../Shader\";\n\nimport type { ImageInfo } from \"./ImageFactory\";\n\nexport interface CubicResampler {\n B: number;\n C: number;\n}\n\nexport interface FilterOptions {\n filter: FilterMode;\n mipmap?: MipmapMode;\n}\n\nexport enum FilterMode {\n Nearest,\n Linear,\n}\n\nexport enum MipmapMode {\n None,\n Nearest,\n Linear,\n}\n\nexport enum ImageFormat {\n JPEG = 3,\n PNG = 4,\n WEBP = 6,\n}\n\nexport interface SkImage extends SkJSIInstance<\"Image\"> {\n /**\n * Returns the possibly scaled height of the image.\n */\n height(): number;\n\n /**\n * Returns the possibly scaled width of the image.\n */\n width(): number;\n\n /**\n * Returns the ImageInfo describing the image.\n */\n getImageInfo(): ImageInfo;\n\n /**\n * Returns the backend texture of the image.\n * The returned object can be used to create a Skia Image object.\n * The returned object is backend specific and should be used with caution.\n * It is the caller's responsibility to ensure that the texture is not used after the image is deleted.\n * The returned object may be null if the image does not have a backend texture.\n *\n * @return backend texture of the image or null\n */\n getNativeTextureUnstable(): unknown;\n\n /**\n * Returns this image as a shader with the specified tiling. It will use cubic sampling.\n * @param tx - tile mode in the x direction.\n * @param ty - tile mode in the y direction.\n * @param fm - The filter mode. (default nearest)\n * @param mm - The mipmap mode. Note: for settings other than None, the image must have mipmaps (default none)\n * calculated with makeCopyWithDefaultMipmaps;\n * @param localMatrix\n */\n makeShaderOptions(\n tx: TileMode,\n ty: TileMode,\n fm: FilterMode,\n mm: MipmapMode,\n localMatrix?: SkMatrix\n ): SkShader;\n\n /**\n * Returns this image as a shader with the specified tiling. It will use cubic sampling.\n * @param tx - tile mode in the x direction.\n * @param ty - tile mode in the y direction.\n * @param B - See CubicResampler in SkSamplingOptions.h for more information\n * @param C - See CubicResampler in SkSamplingOptions.h for more information\n * @param localMatrix\n */\n makeShaderCubic(\n tx: TileMode,\n ty: TileMode,\n B: number,\n C: number,\n localMatrix?: SkMatrix\n ): SkShader;\n\n /** Encodes Image pixels, returning result as UInt8Array. Returns existing\n encoded data if present; otherwise, SkImage is encoded with\n SkEncodedImageFormat::kPNG. Skia must be built with SK_ENCODE_PNG to encode\n SkImage.\n\n Returns nullptr if existing encoded data is missing or invalid, and\n encoding fails.\n\n @param fmt - PNG is the default value.\n @param quality - a value from 0 to 100; 100 is the least lossy. May be ignored.\n\n @return Uint8Array with data\n */\n encodeToBytes(fmt?: ImageFormat, quality?: number): Uint8Array;\n\n /** Encodes Image pixels, returning result as a base64 encoded string. Returns existing\n encoded data if present; otherwise, SkImage is encoded with\n SkEncodedImageFormat::kPNG. Skia must be built with SK_ENCODE_PNG to encode\n SkImage.\n\n Returns nullptr if existing encoded data is missing or invalid, and\n encoding fails.\n\n @param fmt - PNG is the default value.\n @param quality - a value from 0 to 100; 100 is the least lossy. May be ignored.\n\n @return base64 encoded string of data\n */\n encodeToBase64(fmt?: ImageFormat, quality?: number): string;\n\n /** Read Image pixels\n *\n * @param srcX - optional x-axis upper left corner of the rectangle to read from\n * @param srcY - optional y-axis upper left corner of the rectangle to read from\n * @param imageInfo - optional describes the pixel format and dimensions of the data to read into\n * @return Float32Array or Uint8Array with data or null if the read failed.\n */\n readPixels(\n srcX?: number,\n srcY?: number,\n imageInfo?: ImageInfo\n ): Float32Array | Uint8Array | null;\n\n /**\n * Returns raster image or lazy image. Copies SkImage backed by GPU texture\n * into CPU memory if needed. Returns original SkImage if decoded in raster\n * bitmap, or if encoded in a stream.\n */\n makeNonTextureImage(): SkImage;\n}\n"],"mappings":";;;;;;IAiBYA,UAAU,GAAAC,OAAA,CAAAD,UAAA,0BAAVA,UAAU;EAAVA,UAAU,CAAVA,UAAU;EAAVA,UAAU,CAAVA,UAAU;EAAA,OAAVA,UAAU;AAAA;AAAA,IAKVE,UAAU,GAAAD,OAAA,CAAAC,UAAA,0BAAVA,UAAU;EAAVA,UAAU,CAAVA,UAAU;EAAVA,UAAU,CAAVA,UAAU;EAAVA,UAAU,CAAVA,UAAU;EAAA,OAAVA,UAAU;AAAA;AAAA,IAMVC,WAAW,GAAAF,OAAA,CAAAE,WAAA,0BAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAXA,WAAW,CAAXA,WAAW;EAAA,OAAXA,WAAW;AAAA","ignoreList":[]}
@@ -41,6 +41,24 @@ export interface ImageFactory {
41
41
  * native buffer is invalid.
42
42
  */
43
43
  MakeImageFromNativeBuffer: (nativeBuffer: NativeBuffer) => SkImage;
44
+ /**
45
+ *
46
+ * Return an Image backed by a given native texture.
47
+ *
48
+ * The native texture must be a valid owning reference.
49
+ *
50
+ * This API might be used to integrate with other libraries using gpu textures,
51
+ * or to transfer images between different threads.
52
+ *
53
+ * @param texture A native texture handle
54
+ * @param width The width of the texture
55
+ * @param height The height of the texture
56
+ * @param mipmapped Whether the texture is mipmapped
57
+ * @throws Throws an error if the Image could not be created, for example when the given native texture is invalid.
58
+ *
59
+ * @returns Returns a valid SkImage, if the texture is invalid, an error is thrown.
60
+ */
61
+ MakeImageFromNativeTextureUnstable: (texture: unknown, width: number, height: number, mipmapped?: boolean) => SkImage;
44
62
  /**
45
63
  * Returns an image that will be a screenshot of the view represented by
46
64
  * the view tag
@@ -1 +1 @@
1
- {"version":3,"names":["AlphaType","exports"],"sources":["ImageFactory.ts"],"sourcesContent":["import type { SkData } from \"../Data\";\nimport type { NativeBuffer } from \"../NativeBuffer\";\n\nimport type { ColorType } from \"./ColorType\";\nimport type { SkImage } from \"./Image\";\n\nexport enum AlphaType {\n Unknown,\n Opaque,\n Premul,\n Unpremul,\n}\n\nexport interface ImageInfo {\n alphaType: AlphaType;\n // TODO: add support for color space\n // colorSpace: ColorSpace;\n colorType: ColorType;\n height: number;\n width: number;\n}\n\nexport interface ImageFactory {\n /**\n * Return an Image backed by the encoded data, but attempt to defer decoding until the image\n * is actually used/drawn. This deferral allows the system to cache the result, either on the\n * CPU or on the GPU, depending on where the image is drawn.\n * This decoding uses the codecs that have been compiled into CanvasKit. If the bytes are\n * invalid (or an unrecognized codec), null will be returned. See Image.h for more details.\n * @param data - Data object with bytes of data\n * @returns If the encoded format is not supported, or subset is outside of the bounds of the decoded\n * image, nullptr is returned.\n */\n MakeImageFromEncoded: (encoded: SkData) => SkImage | null;\n\n /**\n * Return an Image backed by a given native buffer.\n * The native buffer must be a valid owning reference.\n *\n * For instance, this API is used by\n * [react-native-vision-camera](https://github.com/mrousavy/react-native-vision-camera)\n * to render a Skia Camera preview.\n *\n * - On Android; This is an `AHardwareBuffer*`\n * - On iOS, this is a `CVPixelBufferRef`\n * @param nativeBuffer A strong `uintptr_t` pointer to the native buffer\n * @throws Throws an error if the Image could not be created, for example when the given\n * native buffer is invalid.\n */\n MakeImageFromNativeBuffer: (nativeBuffer: NativeBuffer) => SkImage;\n\n /**\n * Returns an image that will be a screenshot of the view represented by\n * the view tag\n * @param viewTag - The tag of the view to make an image from.\n * @returns Returns a valid SkImage, if the view tag is invalid, nullptr is returned.\n */\n MakeImageFromViewTag: (viewTag: number) => Promise<SkImage | null>;\n\n /**\n * Returns an image with the given pixel data and format.\n * Note that we will always make a copy of the pixel data, because of inconsistencies in\n * behavior between GPU and CPU (i.e. the pixel data will be turned into a GPU texture and\n * not modifiable after creation).\n *\n * @param info\n * @param data - bytes representing the pixel data.\n * @param bytesPerRow\n */\n MakeImage(info: ImageInfo, data: SkData, bytesPerRow: number): SkImage | null;\n}\n"],"mappings":";;;;;;IAMYA,SAAS,GAAAC,OAAA,CAAAD,SAAA,0BAATA,SAAS;EAATA,SAAS,CAATA,SAAS;EAATA,SAAS,CAATA,SAAS;EAATA,SAAS,CAATA,SAAS;EAATA,SAAS,CAATA,SAAS;EAAA,OAATA,SAAS;AAAA","ignoreList":[]}
1
+ {"version":3,"names":["AlphaType","exports"],"sources":["ImageFactory.ts"],"sourcesContent":["import type { SkData } from \"../Data\";\nimport type { NativeBuffer } from \"../NativeBuffer\";\n\nimport type { ColorType } from \"./ColorType\";\nimport type { SkImage } from \"./Image\";\n\nexport enum AlphaType {\n Unknown,\n Opaque,\n Premul,\n Unpremul,\n}\n\nexport interface ImageInfo {\n alphaType: AlphaType;\n // TODO: add support for color space\n // colorSpace: ColorSpace;\n colorType: ColorType;\n height: number;\n width: number;\n}\n\nexport interface ImageFactory {\n /**\n * Return an Image backed by the encoded data, but attempt to defer decoding until the image\n * is actually used/drawn. This deferral allows the system to cache the result, either on the\n * CPU or on the GPU, depending on where the image is drawn.\n * This decoding uses the codecs that have been compiled into CanvasKit. If the bytes are\n * invalid (or an unrecognized codec), null will be returned. See Image.h for more details.\n * @param data - Data object with bytes of data\n * @returns If the encoded format is not supported, or subset is outside of the bounds of the decoded\n * image, nullptr is returned.\n */\n MakeImageFromEncoded: (encoded: SkData) => SkImage | null;\n\n /**\n * Return an Image backed by a given native buffer.\n * The native buffer must be a valid owning reference.\n *\n * For instance, this API is used by\n * [react-native-vision-camera](https://github.com/mrousavy/react-native-vision-camera)\n * to render a Skia Camera preview.\n *\n * - On Android; This is an `AHardwareBuffer*`\n * - On iOS, this is a `CVPixelBufferRef`\n * @param nativeBuffer A strong `uintptr_t` pointer to the native buffer\n * @throws Throws an error if the Image could not be created, for example when the given\n * native buffer is invalid.\n */\n MakeImageFromNativeBuffer: (nativeBuffer: NativeBuffer) => SkImage;\n\n /**\n *\n * Return an Image backed by a given native texture.\n *\n * The native texture must be a valid owning reference.\n *\n * This API might be used to integrate with other libraries using gpu textures,\n * or to transfer images between different threads.\n *\n * @param texture A native texture handle\n * @param width The width of the texture\n * @param height The height of the texture\n * @param mipmapped Whether the texture is mipmapped\n * @throws Throws an error if the Image could not be created, for example when the given native texture is invalid.\n *\n * @returns Returns a valid SkImage, if the texture is invalid, an error is thrown.\n */\n MakeImageFromNativeTextureUnstable: (\n texture: unknown,\n width: number,\n height: number,\n mipmapped?: boolean\n ) => SkImage;\n\n /**\n * Returns an image that will be a screenshot of the view represented by\n * the view tag\n * @param viewTag - The tag of the view to make an image from.\n * @returns Returns a valid SkImage, if the view tag is invalid, nullptr is returned.\n */\n MakeImageFromViewTag: (viewTag: number) => Promise<SkImage | null>;\n\n /**\n * Returns an image with the given pixel data and format.\n * Note that we will always make a copy of the pixel data, because of inconsistencies in\n * behavior between GPU and CPU (i.e. the pixel data will be turned into a GPU texture and\n * not modifiable after creation).\n *\n * @param info\n * @param data - bytes representing the pixel data.\n * @param bytesPerRow\n */\n MakeImage(info: ImageInfo, data: SkData, bytesPerRow: number): SkImage | null;\n}\n"],"mappings":";;;;;;IAMYA,SAAS,GAAAC,OAAA,CAAAD,SAAA,0BAATA,SAAS;EAATA,SAAS,CAATA,SAAS;EAATA,SAAS,CAATA,SAAS;EAATA,SAAS,CAATA,SAAS;EAATA,SAAS,CAATA,SAAS;EAAA,OAATA,SAAS;AAAA","ignoreList":[]}
@@ -100,4 +100,10 @@ export declare const convertToColumnMajor: (rowMajorMatrix: Matrix4) => Matrix4;
100
100
  * @worklet
101
101
  */
102
102
  export declare const convertToAffineMatrix: (m4: Matrix4) => number[];
103
+ /**
104
+ * Inverts a 4x4 matrix
105
+ * @worklet
106
+ * @returns The inverted matrix, or the identity matrix if the input is not invertible
107
+ */
108
+ export declare const invert4: (m: Matrix4) => Matrix4;
103
109
  export {};
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.translate = exports.toMatrix3 = exports.scale = exports.rotateZ = exports.rotateY = exports.rotateX = exports.processTransform3d = exports.pivot = exports.perspective = exports.multiply4 = exports.matrixVecMul4 = exports.mapPoint3d = exports.convertToColumnMajor = exports.convertToAffineMatrix = exports.Matrix4 = void 0;
6
+ exports.translate = exports.toMatrix3 = exports.scale = exports.rotateZ = exports.rotateY = exports.rotateX = exports.processTransform3d = exports.pivot = exports.perspective = exports.multiply4 = exports.matrixVecMul4 = exports.mapPoint3d = exports.invert4 = exports.convertToColumnMajor = exports.convertToAffineMatrix = exports.Matrix4 = void 0;
7
7
  const exhaustiveCheck = a => {
8
8
  "worklet";
9
9
 
@@ -291,5 +291,73 @@ const convertToAffineMatrix = m4 => {
291
291
  // Returning the 6-element affine transformation matrix
292
292
  return [a, b, c, d, tx, ty];
293
293
  };
294
+
295
+ /**
296
+ * Calculates the determinant of a 3x3 matrix
297
+ * @worklet
298
+ */
294
299
  exports.convertToAffineMatrix = convertToAffineMatrix;
300
+ const det3x3 = (a00, a01, a02, a10, a11, a12, a20, a21, a22) => {
301
+ "worklet";
302
+
303
+ return a00 * (a11 * a22 - a12 * a21) + a01 * (a12 * a20 - a10 * a22) + a02 * (a10 * a21 - a11 * a20);
304
+ };
305
+
306
+ /**
307
+ * Inverts a 4x4 matrix
308
+ * @worklet
309
+ * @returns The inverted matrix, or the identity matrix if the input is not invertible
310
+ */
311
+ const invert4 = m => {
312
+ "worklet";
313
+
314
+ const a00 = m[0],
315
+ a01 = m[1],
316
+ a02 = m[2],
317
+ a03 = m[3];
318
+ const a10 = m[4],
319
+ a11 = m[5],
320
+ a12 = m[6],
321
+ a13 = m[7];
322
+ const a20 = m[8],
323
+ a21 = m[9],
324
+ a22 = m[10],
325
+ a23 = m[11];
326
+ const a30 = m[12],
327
+ a31 = m[13],
328
+ a32 = m[14],
329
+ a33 = m[15];
330
+
331
+ // Calculate cofactors
332
+ const b00 = det3x3(a11, a12, a13, a21, a22, a23, a31, a32, a33);
333
+ const b01 = -det3x3(a10, a12, a13, a20, a22, a23, a30, a32, a33);
334
+ const b02 = det3x3(a10, a11, a13, a20, a21, a23, a30, a31, a33);
335
+ const b03 = -det3x3(a10, a11, a12, a20, a21, a22, a30, a31, a32);
336
+ const b10 = -det3x3(a01, a02, a03, a21, a22, a23, a31, a32, a33);
337
+ const b11 = det3x3(a00, a02, a03, a20, a22, a23, a30, a32, a33);
338
+ const b12 = -det3x3(a00, a01, a03, a20, a21, a23, a30, a31, a33);
339
+ const b13 = det3x3(a00, a01, a02, a20, a21, a22, a30, a31, a32);
340
+ const b20 = det3x3(a01, a02, a03, a11, a12, a13, a31, a32, a33);
341
+ const b21 = -det3x3(a00, a02, a03, a10, a12, a13, a30, a32, a33);
342
+ const b22 = det3x3(a00, a01, a03, a10, a11, a13, a30, a31, a33);
343
+ const b23 = -det3x3(a00, a01, a02, a10, a11, a12, a30, a31, a32);
344
+ const b30 = -det3x3(a01, a02, a03, a11, a12, a13, a21, a22, a23);
345
+ const b31 = det3x3(a00, a02, a03, a10, a12, a13, a20, a22, a23);
346
+ const b32 = -det3x3(a00, a01, a03, a10, a11, a13, a20, a21, a23);
347
+ const b33 = det3x3(a00, a01, a02, a10, a11, a12, a20, a21, a22);
348
+
349
+ // Calculate determinant
350
+ const det = a00 * b00 + a01 * b01 + a02 * b02 + a03 * b03;
351
+
352
+ // Check if matrix is invertible
353
+ if (Math.abs(det) < 1e-8) {
354
+ // Return identity matrix if not invertible
355
+ return Matrix4();
356
+ }
357
+ const invDet = 1.0 / det;
358
+
359
+ // Calculate inverse matrix
360
+ return [b00 * invDet, b10 * invDet, b20 * invDet, b30 * invDet, b01 * invDet, b11 * invDet, b21 * invDet, b31 * invDet, b02 * invDet, b12 * invDet, b22 * invDet, b32 * invDet, b03 * invDet, b13 * invDet, b23 * invDet, b33 * invDet];
361
+ };
362
+ exports.invert4 = invert4;
295
363
  //# sourceMappingURL=Matrix4.js.map