@shopify/react-native-skia 1.5.2 → 1.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. package/android/CMakeLists.txt +52 -13
  2. package/android/build.gradle +3 -0
  3. package/android/cpp/rnskia-android/RNSkAndroidPlatformContext.h +18 -1
  4. package/android/cpp/rnskia-android/RNSkAndroidVideo.cpp +12 -1
  5. package/android/cpp/rnskia-android/RNSkOpenGLCanvasProvider.cpp +13 -0
  6. package/android/src/main/java/com/shopify/reactnative/skia/SkiaBaseView.java +0 -1
  7. package/cpp/api/JsiSkImage.h +15 -2
  8. package/cpp/api/JsiSkSurface.h +18 -3
  9. package/cpp/rnskia/DawnContext.h +241 -0
  10. package/cpp/rnskia/DawnUtils.h +127 -0
  11. package/cpp/rnskia/DawnWindowContext.cpp +19 -0
  12. package/cpp/rnskia/DawnWindowContext.h +77 -0
  13. package/cpp/rnskia/ImageProvider.h +100 -0
  14. package/cpp/rnskia/RNSkView.h +6 -0
  15. package/cpp/skia/include/android/SkAnimatedImage.h +14 -0
  16. package/cpp/skia/include/codec/SkAvifDecoder.h +39 -3
  17. package/cpp/skia/include/codec/SkCodec.h +16 -0
  18. package/cpp/skia/include/config/SkUserConfig.h +3 -2
  19. package/cpp/skia/include/core/SkCanvas.h +55 -10
  20. package/cpp/skia/include/core/SkContourMeasure.h +76 -0
  21. package/cpp/skia/include/core/SkFontScanner.h +48 -0
  22. package/cpp/skia/include/core/SkMilestone.h +1 -1
  23. package/cpp/skia/include/core/SkPath.h +11 -0
  24. package/cpp/skia/include/core/SkPathEffect.h +0 -23
  25. package/cpp/skia/include/core/SkRect.h +2 -0
  26. package/cpp/skia/include/core/SkString.h +4 -0
  27. package/cpp/skia/include/core/SkTypeface.h +5 -0
  28. package/cpp/skia/include/core/SkTypes.h +8 -3
  29. package/cpp/skia/include/docs/SkPDFDocument.h +3 -3
  30. package/cpp/skia/include/effects/SkOverdrawColorFilter.h +1 -0
  31. package/cpp/skia/include/effects/SkRuntimeEffect.h +2 -1
  32. package/cpp/skia/include/encode/SkJpegEncoder.h +4 -0
  33. package/cpp/skia/include/gpu/ganesh/GrContextOptions.h +8 -1
  34. package/cpp/skia/include/gpu/ganesh/GrDirectContext.h +18 -3
  35. package/cpp/skia/include/gpu/ganesh/GrTypes.h +11 -0
  36. package/cpp/skia/include/gpu/ganesh/gl/GrGLFunctions.h +5 -1
  37. package/cpp/skia/include/gpu/ganesh/gl/GrGLInterface.h +0 -1
  38. package/cpp/skia/include/gpu/graphite/GraphiteTypes.h +8 -0
  39. package/cpp/skia/include/gpu/graphite/Recorder.h +0 -2
  40. package/cpp/skia/include/gpu/graphite/precompile/PaintOptions.h +7 -4
  41. package/cpp/skia/include/gpu/graphite/precompile/PrecompileImageFilter.h +2 -0
  42. package/cpp/skia/include/gpu/graphite/precompile/PrecompileMaskFilter.h +2 -0
  43. package/cpp/skia/include/ports/SkFontMgr_android_ndk.h +25 -0
  44. package/cpp/skia/include/ports/SkFontMgr_fontconfig.h +4 -2
  45. package/cpp/skia/include/ports/SkFontScanner_Fontations.h +15 -0
  46. package/cpp/skia/include/ports/SkFontScanner_FreeType.h +15 -0
  47. package/cpp/skia/include/private/SkExif.h +14 -0
  48. package/cpp/skia/include/private/SkPathRef.h +36 -0
  49. package/cpp/skia/include/private/base/SkFeatures.h +4 -0
  50. package/cpp/skia/include/private/base/SkSpan_impl.h +1 -3
  51. package/cpp/skia/modules/skcms/src/skcms_internals.h +3 -0
  52. package/cpp/skia/src/base/SkMathPriv.h +1 -8
  53. package/ios/RNSkia-iOS/RNSkMetalCanvasProvider.h +1 -2
  54. package/ios/RNSkia-iOS/RNSkMetalCanvasProvider.mm +25 -19
  55. package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +23 -0
  56. package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.h +23 -9
  57. package/ios/RNSkia-iOS/SkiaMetalSurfaceFactory.mm +0 -20
  58. package/libs/android/arm64-v8a/libskia.a +0 -0
  59. package/libs/android/arm64-v8a/libskottie.a +0 -0
  60. package/libs/android/armeabi-v7a/libskia.a +0 -0
  61. package/libs/android/armeabi-v7a/libskottie.a +0 -0
  62. package/libs/android/x86/libskia.a +0 -0
  63. package/libs/android/x86/libskottie.a +0 -0
  64. package/libs/android/x86_64/libskia.a +0 -0
  65. package/libs/android/x86_64/libskottie.a +0 -0
  66. package/libs/ios/libskia.xcframework/ios-arm64_arm64e/libskia.a +0 -0
  67. package/libs/ios/libskia.xcframework/ios-arm64_arm64e_x86_64-simulator/libskia.a +0 -0
  68. package/libs/ios/libskottie.xcframework/ios-arm64_arm64e/libskottie.a +0 -0
  69. package/libs/ios/libskottie.xcframework/ios-arm64_arm64e_x86_64-simulator/libskottie.a +0 -0
  70. package/libs/ios/libskparagraph.xcframework/ios-arm64_arm64e/libskparagraph.a +0 -0
  71. package/libs/ios/libskparagraph.xcframework/ios-arm64_arm64e_x86_64-simulator/libskparagraph.a +0 -0
  72. package/libs/ios/libsksg.xcframework/ios-arm64_arm64e/libsksg.a +0 -0
  73. package/libs/ios/libsksg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsksg.a +0 -0
  74. package/libs/ios/libskshaper.xcframework/Info.plist +5 -5
  75. package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e/libskshaper.a +0 -0
  76. package/libs/ios/libskshaper.xcframework/ios-arm64_arm64e_x86_64-simulator/libskshaper.a +0 -0
  77. package/libs/ios/libskunicode_core.xcframework/Info.plist +5 -5
  78. package/libs/ios/libskunicode_core.xcframework/ios-arm64_arm64e/libskunicode_core.a +0 -0
  79. package/libs/ios/libskunicode_core.xcframework/ios-arm64_arm64e_x86_64-simulator/libskunicode_core.a +0 -0
  80. package/libs/ios/libskunicode_libgrapheme.xcframework/Info.plist +5 -5
  81. package/libs/ios/libskunicode_libgrapheme.xcframework/ios-arm64_arm64e/libskunicode_libgrapheme.a +0 -0
  82. package/libs/ios/libskunicode_libgrapheme.xcframework/ios-arm64_arm64e_x86_64-simulator/libskunicode_libgrapheme.a +0 -0
  83. package/libs/ios/libsvg.xcframework/ios-arm64_arm64e/libsvg.a +0 -0
  84. package/libs/ios/libsvg.xcframework/ios-arm64_arm64e_x86_64-simulator/libsvg.a +0 -0
  85. package/package.json +1 -1
  86. package/react-native-skia.podspec +35 -9
  87. package/src/renderer/__tests__/e2e/SVG.spec.tsx +2 -1
@@ -0,0 +1,127 @@
1
+ #pragma once
2
+
3
+ #include "webgpu/webgpu_cpp.h"
4
+
5
+ #include "dawn/dawn_proc.h"
6
+ #include "dawn/native/DawnNative.h"
7
+
8
+ #include "include/core/SkColorType.h"
9
+ #include "include/gpu/graphite/dawn/DawnBackendContext.h"
10
+
11
+ namespace DawnUtils {
12
+
13
+ #ifdef __APPLE__
14
+ static const SkColorType PreferedColorType = kBGRA_8888_SkColorType;
15
+ static const wgpu::TextureFormat PreferredTextureFormat =
16
+ wgpu::TextureFormat::BGRA8Unorm;
17
+ #else
18
+ static const SkColorType PreferedColorType = kRGBA_8888_SkColorType;
19
+ static const wgpu::TextureFormat PreferredTextureFormat =
20
+ wgpu::TextureFormat::RGBA8Unorm;
21
+ #endif
22
+
23
+ inline skgpu::graphite::DawnBackendContext
24
+ createDawnBackendContext(dawn::native::Instance *instance) {
25
+
26
+ auto useTintIR = false;
27
+ static constexpr const char *kToggles[] = {
28
+ "allow_unsafe_apis",
29
+ "use_user_defined_labels_in_backend",
30
+ "disable_robustness",
31
+ "use_tint_ir",
32
+ };
33
+ wgpu::DawnTogglesDescriptor togglesDesc;
34
+ togglesDesc.enabledToggleCount = std::size(kToggles) - (useTintIR ? 0 : 1);
35
+ togglesDesc.enabledToggles = kToggles;
36
+
37
+ wgpu::RequestAdapterOptions options;
38
+ #ifdef __APPLE__
39
+ constexpr auto kDefaultBackendType = wgpu::BackendType::Metal;
40
+ #elif __ANDROID__
41
+ constexpr auto kDefaultBackendType = wgpu::BackendType::Vulkan;
42
+ #endif
43
+ options.backendType = kDefaultBackendType;
44
+ options.nextInChain = &togglesDesc;
45
+
46
+ std::vector<dawn::native::Adapter> adapters =
47
+ instance->EnumerateAdapters(&options);
48
+ if (adapters.empty()) {
49
+ throw std::runtime_error("No matching adapter found");
50
+ }
51
+
52
+ wgpu::Adapter adapter = adapters[0].Get();
53
+
54
+ std::vector<wgpu::FeatureName> features;
55
+ if (adapter.HasFeature(wgpu::FeatureName::MSAARenderToSingleSampled)) {
56
+ features.push_back(wgpu::FeatureName::MSAARenderToSingleSampled);
57
+ }
58
+ if (adapter.HasFeature(wgpu::FeatureName::TransientAttachments)) {
59
+ features.push_back(wgpu::FeatureName::TransientAttachments);
60
+ }
61
+ if (adapter.HasFeature(wgpu::FeatureName::Unorm16TextureFormats)) {
62
+ features.push_back(wgpu::FeatureName::Unorm16TextureFormats);
63
+ }
64
+ if (adapter.HasFeature(wgpu::FeatureName::DualSourceBlending)) {
65
+ features.push_back(wgpu::FeatureName::DualSourceBlending);
66
+ }
67
+ if (adapter.HasFeature(wgpu::FeatureName::FramebufferFetch)) {
68
+ features.push_back(wgpu::FeatureName::FramebufferFetch);
69
+ }
70
+ if (adapter.HasFeature(wgpu::FeatureName::BufferMapExtendedUsages)) {
71
+ features.push_back(wgpu::FeatureName::BufferMapExtendedUsages);
72
+ }
73
+ if (adapter.HasFeature(wgpu::FeatureName::TextureCompressionETC2)) {
74
+ features.push_back(wgpu::FeatureName::TextureCompressionETC2);
75
+ }
76
+ if (adapter.HasFeature(wgpu::FeatureName::TextureCompressionBC)) {
77
+ features.push_back(wgpu::FeatureName::TextureCompressionBC);
78
+ }
79
+ if (adapter.HasFeature(wgpu::FeatureName::R8UnormStorage)) {
80
+ features.push_back(wgpu::FeatureName::R8UnormStorage);
81
+ }
82
+ if (adapter.HasFeature(wgpu::FeatureName::DawnLoadResolveTexture)) {
83
+ features.push_back(wgpu::FeatureName::DawnLoadResolveTexture);
84
+ }
85
+ if (adapter.HasFeature(wgpu::FeatureName::DawnPartialLoadResolveTexture)) {
86
+ features.push_back(wgpu::FeatureName::DawnPartialLoadResolveTexture);
87
+ }
88
+ #ifdef __APPLE__
89
+ if (adapter.HasFeature(wgpu::FeatureName::SharedTextureMemoryIOSurface)) {
90
+ features.push_back(wgpu::FeatureName::SharedTextureMemoryIOSurface);
91
+ }
92
+ #else
93
+ if (adapter.HasFeature(
94
+ wgpu::FeatureName::SharedTextureMemoryAHardwareBuffer)) {
95
+ features.push_back(wgpu::FeatureName::SharedTextureMemoryAHardwareBuffer);
96
+ }
97
+ #endif
98
+
99
+ wgpu::DeviceDescriptor desc;
100
+ desc.requiredFeatureCount = features.size();
101
+ desc.requiredFeatures = features.data();
102
+ desc.nextInChain = &togglesDesc;
103
+ desc.SetDeviceLostCallback(
104
+ wgpu::CallbackMode::AllowSpontaneous,
105
+ [](const wgpu::Device &, wgpu::DeviceLostReason reason,
106
+ const char *message) {
107
+ if (reason != wgpu::DeviceLostReason::Destroyed) {
108
+ SK_ABORT("Device lost: %s\n", message);
109
+ }
110
+ });
111
+ desc.SetUncapturedErrorCallback(
112
+ [](const wgpu::Device &, wgpu::ErrorType, const char *message) {
113
+ SkDebugf("Device error: %s\n", message);
114
+ });
115
+
116
+ wgpu::Device device = adapter.CreateDevice(&desc);
117
+ SkASSERT(device);
118
+
119
+ skgpu::graphite::DawnBackendContext backendContext;
120
+ backendContext.fInstance = wgpu::Instance(instance->Get());
121
+ backendContext.fDevice = device;
122
+ backendContext.fQueue = device.GetQueue();
123
+
124
+ return backendContext;
125
+ }
126
+
127
+ } // namespace DawnUtils
@@ -0,0 +1,19 @@
1
+ #include "DawnWindowContext.h"
2
+
3
+ #include "DawnContext.h"
4
+
5
+ namespace RNSkia {
6
+
7
+ void DawnWindowContext::present() {
8
+ auto recording = _recorder->snap();
9
+ if (!recording) {
10
+ throw std::runtime_error("Failed to create graphite recording");
11
+ }
12
+ DawnContext::getInstance().submitRecording(recording.get());
13
+ #ifdef __APPLE__
14
+ dawn::native::metal::WaitForCommandsToBeScheduled(_device.Get());
15
+ #endif
16
+ _surface.Present();
17
+ }
18
+
19
+ } // namespace RNSkia
@@ -0,0 +1,77 @@
1
+ #pragma once
2
+
3
+ #include "DawnUtils.h"
4
+ #include "WindowContext.h"
5
+
6
+ #include "dawn/native/MetalBackend.h"
7
+ #include "webgpu/webgpu_cpp.h"
8
+
9
+ #include "include/core/SkColorSpace.h"
10
+
11
+ #include "include/gpu/graphite/BackendTexture.h"
12
+ #include "include/gpu/graphite/Context.h"
13
+ #include "include/gpu/graphite/ContextOptions.h"
14
+ #include "include/gpu/graphite/GraphiteTypes.h"
15
+ #include "include/gpu/graphite/Recorder.h"
16
+ #include "include/gpu/graphite/Recording.h"
17
+ #include "include/gpu/graphite/Surface.h"
18
+ #include "include/gpu/graphite/dawn/DawnBackendContext.h"
19
+ #include "include/gpu/graphite/dawn/DawnTypes.h"
20
+ #include "include/gpu/graphite/dawn/DawnUtils.h"
21
+
22
+ namespace RNSkia {
23
+
24
+ class DawnWindowContext : public WindowContext {
25
+ public:
26
+ DawnWindowContext(skgpu::graphite::Recorder *recorder, wgpu::Device device,
27
+ wgpu::Surface surface, int width, int height)
28
+ : _recorder(recorder), _device(device), _surface(surface), _width(width),
29
+ _height(height) {
30
+ wgpu::SurfaceConfiguration config;
31
+ config.device = _device;
32
+ config.format = DawnUtils::PreferredTextureFormat;
33
+ config.width = _width;
34
+ config.height = _height;
35
+ #ifdef __APPLE__
36
+ config.alphaMode = wgpu::CompositeAlphaMode::Premultiplied;
37
+ #endif
38
+ _surface.Configure(&config);
39
+ }
40
+
41
+ sk_sp<SkSurface> getSurface() override {
42
+ wgpu::SurfaceTexture surfaceTexture;
43
+ _surface.GetCurrentTexture(&surfaceTexture);
44
+ auto texture = surfaceTexture.texture;
45
+ skgpu::graphite::DawnTextureInfo info(
46
+ /*sampleCount=*/1, skgpu::Mipmapped::kNo,
47
+ DawnUtils::PreferredTextureFormat, texture.GetUsage(),
48
+ wgpu::TextureAspect::All);
49
+ auto backendTex = skgpu::graphite::BackendTextures::MakeDawn(texture.Get());
50
+ sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGB();
51
+ SkSurfaceProps surfaceProps;
52
+ auto surface = SkSurfaces::WrapBackendTexture(_recorder, backendTex,
53
+ DawnUtils::PreferedColorType,
54
+ colorSpace, &surfaceProps);
55
+ return surface;
56
+ }
57
+
58
+ void present() override;
59
+
60
+ void resize(int width, int height) override {
61
+ throw std::runtime_error("resize not implemented yet");
62
+ }
63
+
64
+ int getWidth() override { return _width; }
65
+
66
+ int getHeight() override { return _height; }
67
+
68
+ private:
69
+ skgpu::graphite::Recorder *_recorder;
70
+ // TODO: keep device in DawnContext? Do we need it for resizing?
71
+ wgpu::Device _device;
72
+ wgpu::Surface _surface;
73
+ int _width;
74
+ int _height;
75
+ };
76
+
77
+ } // namespace RNSkia
@@ -0,0 +1,100 @@
1
+ #pragma once
2
+
3
+ #include "include/core/SkCanvas.h"
4
+ #include "include/core/SkImage.h"
5
+
6
+ #include "include/core/SkTiledImageUtils.h"
7
+ #include "include/gpu/graphite/Image.h"
8
+ #include "include/gpu/graphite/ImageProvider.h"
9
+ #include "include/gpu/graphite/Recorder.h"
10
+ #include "src/core/SkLRUCache.h"
11
+
12
+ namespace RNSkia {
13
+
14
+ // Currently, we give each new Recorder its own ImageProvider. This means we
15
+ // don't have to deal w/ any threading issues.
16
+ // TODO: We should probably have this class generate and report some cache stats
17
+ // TODO: Hook up to listener system?
18
+ // TODO: add testing of a single ImageProvider passed to multiple recorders
19
+ class ImageProvider : public skgpu::graphite::ImageProvider {
20
+ public:
21
+ ImageProvider() : fCache(kDefaultNumCachedImages) {}
22
+ ~ImageProvider() override {}
23
+
24
+ static sk_sp<ImageProvider> Make() { return sk_ref_sp(new ImageProvider); }
25
+
26
+ sk_sp<SkImage>
27
+ findOrCreate(skgpu::graphite::Recorder *recorder, const SkImage *image,
28
+ SkImage::RequiredProperties requiredProps) override {
29
+ if (!requiredProps.fMipmapped) {
30
+ // If no mipmaps are required, check to see if we have a mipmapped version
31
+ // anyway - since it can be used in that case.
32
+ // TODO: we could get fancy and, if ever a mipmapped key eclipsed a
33
+ // non-mipmapped key, we could remove the hidden non-mipmapped key/image
34
+ // from the cache.
35
+ ImageKey mipMappedKey(image, /* mipmapped= */ true);
36
+ auto result = fCache.find(mipMappedKey);
37
+ if (result) {
38
+ return *result;
39
+ }
40
+ }
41
+
42
+ ImageKey key(image, requiredProps.fMipmapped);
43
+
44
+ auto result = fCache.find(key);
45
+ if (result) {
46
+ return *result;
47
+ }
48
+
49
+ sk_sp<SkImage> newImage =
50
+ SkImages::TextureFromImage(recorder, image, requiredProps);
51
+ if (!newImage) {
52
+ return nullptr;
53
+ }
54
+
55
+ result = fCache.insert(key, std::move(newImage));
56
+ SkASSERT(result);
57
+
58
+ return *result;
59
+ }
60
+
61
+ private:
62
+ static constexpr int kDefaultNumCachedImages = 256;
63
+
64
+ class ImageKey {
65
+ public:
66
+ ImageKey(const SkImage *image, bool mipmapped) {
67
+ uint32_t flags = mipmapped ? 0x1 : 0x0;
68
+ SkTiledImageUtils::GetImageKeyValues(image, &fValues[1]);
69
+ fValues[kNumValues - 1] = flags;
70
+ fValues[0] =
71
+ SkChecksum::Hash32(&fValues[1], (kNumValues - 1) * sizeof(uint32_t));
72
+ }
73
+
74
+ uint32_t hash() const { return fValues[0]; }
75
+
76
+ bool operator==(const ImageKey &other) const {
77
+ for (int i = 0; i < kNumValues; ++i) {
78
+ if (fValues[i] != other.fValues[i]) {
79
+ return false;
80
+ }
81
+ }
82
+
83
+ return true;
84
+ }
85
+ bool operator!=(const ImageKey &other) const { return !(*this == other); }
86
+
87
+ private:
88
+ static const int kNumValues = SkTiledImageUtils::kNumImageKeyValues + 2;
89
+
90
+ uint32_t fValues[kNumValues];
91
+ };
92
+
93
+ struct ImageHash {
94
+ size_t operator()(const ImageKey &key) const { return key.hash(); }
95
+ };
96
+
97
+ SkLRUCache<ImageKey, sk_sp<SkImage>, ImageHash> fCache;
98
+ };
99
+
100
+ } // namespace RNSkia
@@ -108,7 +108,13 @@ public:
108
108
  } else {
109
109
  image = _surface->makeImageSnapshot();
110
110
  }
111
+ #if defined(SK_GRAPHITE)
112
+ DawnContext::getInstance().submitRecording(
113
+ _surface->recorder()->snap().get());
114
+ return DawnContext::getInstance().MakeRasterImage(image);
115
+ #else
111
116
  return image->makeNonTextureImage();
117
+ #endif
112
118
  }
113
119
 
114
120
  /**
@@ -110,6 +110,19 @@ public:
110
110
  */
111
111
  int getFrameCount() const { return fFrameCount; }
112
112
 
113
+ /**
114
+ * Change the filter mode.
115
+ *
116
+ * By default, the image will apply bilinear filtering when drawing in the
117
+ * OnDraw method.
118
+ */
119
+ void setFilterMode(SkFilterMode filterMode);
120
+
121
+ /**
122
+ * Return the filter mode used for sampling when drawing.
123
+ */
124
+ SkFilterMode getFilterMode() const { return fFilterMode; }
125
+
113
126
  protected:
114
127
  SkRect onGetBounds() override;
115
128
  void onDraw(SkCanvas*) override;
@@ -152,6 +165,7 @@ private:
152
165
  Frame fRestoreFrame;
153
166
  int fRepetitionCount;
154
167
  int fRepetitionsCompleted;
168
+ SkFilterMode fFilterMode = SkFilterMode::kLinear;
155
169
 
156
170
  SkAnimatedImage(std::unique_ptr<SkAndroidCodec>, const SkImageInfo& requestedInfo,
157
171
  SkIRect cropRect, sk_sp<SkPicture> postProcess);
@@ -18,13 +18,15 @@ class SkStream;
18
18
 
19
19
  namespace SkAvifDecoder {
20
20
 
21
- /** Returns true if this data claims to be a AVIF image. */
21
+ namespace LibAvif {
22
+
23
+ /** Returns true if this data claims to be an AVIF image. */
22
24
  SK_API bool IsAvif(const void*, size_t);
23
25
 
24
26
  /**
25
- * Attempts to decode the given bytes as a AVIF.
27
+ * Attempts to decode the given bytes as an AVIF.
26
28
  *
27
- * If the bytes are not a AVIF, returns nullptr.
29
+ * If the bytes are not an AVIF, returns nullptr.
28
30
  *
29
31
  * DecodeContext is ignored
30
32
  */
@@ -39,6 +41,40 @@ inline constexpr SkCodecs::Decoder Decoder() {
39
41
  return { "avif", IsAvif, Decode };
40
42
  }
41
43
 
44
+ } // namespace LibAvif
45
+
46
+ // This function is in the root SkAvifDecoder namespace. It simply routes
47
+ // everything through the LibAvif namespace and exists for backwards
48
+ // compatibility.
49
+ inline constexpr SkCodecs::Decoder Decoder() {
50
+ return { "avif", LibAvif::IsAvif, LibAvif::Decode };
51
+ }
52
+
53
+ namespace CrabbyAvif {
54
+
55
+ /** Returns true if this data claims to be an AVIF image. */
56
+ SK_API bool IsAvif(const void*, size_t);
57
+
58
+ /**
59
+ * Attempts to decode the given bytes as an AVIF.
60
+ *
61
+ * If the bytes are not an AVIF, returns nullptr.
62
+ *
63
+ * DecodeContext is ignored
64
+ */
65
+ SK_API std::unique_ptr<SkCodec> Decode(std::unique_ptr<SkStream>,
66
+ SkCodec::Result*,
67
+ SkCodecs::DecodeContext = nullptr);
68
+ SK_API std::unique_ptr<SkCodec> Decode(sk_sp<SkData>,
69
+ SkCodec::Result*,
70
+ SkCodecs::DecodeContext = nullptr);
71
+
72
+ inline constexpr SkCodecs::Decoder Decoder() {
73
+ return { "avif", IsAvif, Decode };
74
+ }
75
+
76
+ } // namespace CrabbyAvif
77
+
42
78
  } // namespace SkAvifDecoder
43
79
 
44
80
  #endif // SkAvifDecoder_DEFINED
@@ -239,6 +239,16 @@ public:
239
239
  return this->getEncodedInfo().profile();
240
240
  }
241
241
 
242
+ /**
243
+ * Whether the encoded input uses 16 or more bits per component.
244
+ */
245
+ bool hasHighBitDepthEncodedData() const {
246
+ // API design note: We don't return `bitsPerComponent` because it may be
247
+ // misleading in some cases - see https://crbug.com/359350061#comment4
248
+ // for more details.
249
+ return this->getEncodedInfo().bitsPerComponent() >= 16;
250
+ }
251
+
242
252
  /**
243
253
  * Returns the image orientation stored in the EXIF data.
244
254
  * If there is no EXIF data, or if we cannot read the EXIF data, returns kTopLeft.
@@ -637,6 +647,12 @@ public:
637
647
  * Return the number of frames in the image.
638
648
  *
639
649
  * May require reading through the stream.
650
+ *
651
+ * Note that some codecs may be unable to gather `FrameInfo` for all frames
652
+ * in case of `kIncompleteInput`. For such codecs `getFrameCount` may
653
+ * initially report a low frame count. After the underlying `SkStream`
654
+ * provides additional data, then calling `getFrameCount` again may return
655
+ * an updated, increased frame count.
640
656
  */
641
657
  int getFrameCount() {
642
658
  return this->onGetFrameCount();
@@ -90,9 +90,10 @@
90
90
  integrate with their histogram collection backend.
91
91
  */
92
92
  //#define SK_HISTOGRAM_BOOLEAN(name, sample)
93
- //#define SK_HISTOGRAM_ENUMERATION(name, sample, enum_size)
94
- //#define SK_HISTOGRAM_EXACT_LINEAR(name, sample, value_max)
93
+ //#define SK_HISTOGRAM_ENUMERATION(name, sampleEnum, enumSize)
94
+ //#define SK_HISTOGRAM_EXACT_LINEAR(name, sample, valueMax)
95
95
  //#define SK_HISTOGRAM_MEMORY_KB(name, sample)
96
+ //#define SK_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(name, sampleUSec, minUSec, maxUSec, bucketCount)
96
97
 
97
98
  // To use smaller but slower mipmap builder
98
99
  //#define SK_USE_DRAWING_MIPMAP_DOWNSAMPLER
@@ -28,6 +28,7 @@
28
28
  #include "include/core/SkSpan.h"
29
29
  #include "include/core/SkString.h"
30
30
  #include "include/core/SkSurfaceProps.h"
31
+ #include "include/core/SkTileMode.h"
31
32
  #include "include/core/SkTypes.h"
32
33
  #include "include/private/base/SkCPUTypes.h"
33
34
  #include "include/private/base/SkDeque.h"
@@ -700,7 +701,8 @@ public:
700
701
  @return SaveLayerRec with empty fBackdrop
701
702
  */
702
703
  SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
703
- : SaveLayerRec(bounds, paint, nullptr, nullptr, 1.f, saveLayerFlags, /*filters=*/{}) {}
704
+ : SaveLayerRec(bounds, paint, nullptr, nullptr, 1.f, SkTileMode::kClamp,
705
+ saveLayerFlags, /*filters=*/{}) {}
704
706
 
705
707
  /** Sets fBounds, fPaint, fBackdrop, and fSaveLayerFlags.
706
708
 
@@ -716,9 +718,10 @@ public:
716
718
  */
717
719
  SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
718
720
  SaveLayerFlags saveLayerFlags)
719
- : SaveLayerRec(bounds, paint, backdrop, nullptr, 1.f, saveLayerFlags, /*filters=*/{}) {}
721
+ : SaveLayerRec(bounds, paint, backdrop, nullptr, 1.f, SkTileMode::kClamp,
722
+ saveLayerFlags, /*filters=*/{}) {}
720
723
 
721
- /** Sets fBounds, fColorSpace, and fSaveLayerFlags.
724
+ /** Sets fBounds, fBackdrop, fColorSpace, and fSaveLayerFlags.
722
725
 
723
726
  @param bounds layer dimensions; may be nullptr
724
727
  @param paint applied to layer when overlaying prior layer;
@@ -738,15 +741,44 @@ public:
738
741
  */
739
742
  SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
740
743
  const SkColorSpace* colorSpace, SaveLayerFlags saveLayerFlags)
741
- : SaveLayerRec(bounds, paint, backdrop, colorSpace, 1.f, saveLayerFlags, /*filters=*/{}) {}
744
+ : SaveLayerRec(bounds, paint, backdrop, colorSpace, 1.f, SkTileMode::kClamp,
745
+ saveLayerFlags, /*filters=*/{}) {}
746
+
747
+
748
+ /** Sets fBounds, fBackdrop, fBackdropTileMode, fColorSpace, and fSaveLayerFlags.
749
+
750
+ @param bounds layer dimensions; may be nullptr
751
+ @param paint applied to layer when overlaying prior layer;
752
+ may be nullptr
753
+ @param backdrop If not null, this causes the current layer to be filtered by
754
+ backdrop, and then drawn into the new layer
755
+ (respecting the current clip).
756
+ If null, the new layer is initialized with transparent-black.
757
+ @param backdropTileMode If the 'backdrop' is not null, or 'saveLayerFlags' has
758
+ kInitWithPrevious set, this tile mode is used when the new layer
759
+ would read outside the backdrop image's available content.
760
+ @param colorSpace If not null, when the layer is restored, a color space
761
+ conversion will be applied from this color space to the parent's
762
+ color space. The restore paint and backdrop filters will be
763
+ applied in this color space.
764
+ If null, the new layer will inherit the color space from its
765
+ parent.
766
+ @param saveLayerFlags SaveLayerRec options to modify layer
767
+ @return SaveLayerRec fully specified
768
+ */
769
+ SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
770
+ SkTileMode backdropTileMode, const SkColorSpace* colorSpace,
771
+ SaveLayerFlags saveLayerFlags)
772
+ : SaveLayerRec(bounds, paint, backdrop, colorSpace, 1.f, backdropTileMode,
773
+ saveLayerFlags, /*filters=*/{}) {}
742
774
 
743
775
  /** hints at layer size limit */
744
- const SkRect* fBounds = nullptr;
776
+ const SkRect* fBounds = nullptr;
745
777
 
746
778
  /** modifies overlay */
747
- const SkPaint* fPaint = nullptr;
779
+ const SkPaint* fPaint = nullptr;
748
780
 
749
- FilterSpan fFilters = {};
781
+ FilterSpan fFilters = {};
750
782
 
751
783
  /**
752
784
  * If not null, this triggers the same initialization behavior as setting
@@ -754,17 +786,24 @@ public:
754
786
  * the new layer, rather than initializing the new layer with transparent-black.
755
787
  * This is then filtered by fBackdrop (respecting the current clip).
756
788
  */
757
- const SkImageFilter* fBackdrop = nullptr;
789
+ const SkImageFilter* fBackdrop = nullptr;
790
+
791
+ /**
792
+ * If the layer is initialized with prior content (and/or with a backdrop filter) and this
793
+ * would require sampling outside of the available backdrop, this is the tilemode applied
794
+ * to the boundary of the prior layer's image.
795
+ */
796
+ SkTileMode fBackdropTileMode = SkTileMode::kClamp;
758
797
 
759
798
  /**
760
799
  * If not null, this triggers a color space conversion when the layer is restored. It
761
800
  * will be as if the layer's contents are drawn in this color space. Filters from
762
801
  * fBackdrop and fPaint will be applied in this color space.
763
802
  */
764
- const SkColorSpace* fColorSpace = nullptr;
803
+ const SkColorSpace* fColorSpace = nullptr;
765
804
 
766
805
  /** preserves LCD text, creates with prior layer contents */
767
- SaveLayerFlags fSaveLayerFlags = 0;
806
+ SaveLayerFlags fSaveLayerFlags = 0;
768
807
 
769
808
  private:
770
809
  friend class SkCanvas;
@@ -775,12 +814,14 @@ public:
775
814
  const SkImageFilter* backdrop,
776
815
  const SkColorSpace* colorSpace,
777
816
  SkScalar backdropScale,
817
+ SkTileMode backdropTileMode,
778
818
  SaveLayerFlags saveLayerFlags,
779
819
  FilterSpan filters)
780
820
  : fBounds(bounds)
781
821
  , fPaint(paint)
782
822
  , fFilters(filters)
783
823
  , fBackdrop(backdrop)
824
+ , fBackdropTileMode(backdropTileMode)
784
825
  , fColorSpace(colorSpace)
785
826
  , fSaveLayerFlags(saveLayerFlags)
786
827
  , fExperimentalBackdropScale(backdropScale) {
@@ -2591,12 +2632,16 @@ private:
2591
2632
  * before any filtering, or as part of the copy, and is then drawn with 1/scaleFactor to 'dst'.
2592
2633
  * Must be 1.0 if 'compat' is kYes (i.e. any scale factor has already been baked into the
2593
2634
  * relative transforms between the devices).
2635
+ *
2636
+ * 'srcTileMode' is the tile mode to apply to the boundary of the 'src' image when insufficient
2637
+ * content is available. It defaults to kDecal for the regular saveLayer() case.
2594
2638
  */
2595
2639
  void internalDrawDeviceWithFilter(SkDevice* src, SkDevice* dst,
2596
2640
  FilterSpan filters, const SkPaint& paint,
2597
2641
  DeviceCompatibleWithFilter compat,
2598
2642
  const SkColorInfo& filterColorInfo,
2599
2643
  SkScalar scaleFactor = 1.f,
2644
+ SkTileMode srcTileMode = SkTileMode::kDecal,
2600
2645
  bool srcIsCoverageLayer = false);
2601
2646
 
2602
2647
  /*