diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index 63e60ced536..e63416129d8 100644 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -55286,6 +55286,8 @@ FILE: ../../../flutter/lib/web_ui/skwasm/fonts.cpp FILE: ../../../flutter/lib/web_ui/skwasm/helpers.h FILE: ../../../flutter/lib/web_ui/skwasm/image.cpp FILE: ../../../flutter/lib/web_ui/skwasm/library_skwasm_support.js +FILE: ../../../flutter/lib/web_ui/skwasm/live_objects.cpp +FILE: ../../../flutter/lib/web_ui/skwasm/live_objects.h FILE: ../../../flutter/lib/web_ui/skwasm/paint.cpp FILE: ../../../flutter/lib/web_ui/skwasm/path.cpp FILE: ../../../flutter/lib/web_ui/skwasm/picture.cpp diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/scene_view.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/scene_view.dart index 69e030adb3f..3bfc0c928a6 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/scene_view.dart +++ b/engine/src/flutter/lib/web_ui/lib/src/engine/scene_view.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:convert'; import 'package:ui/src/engine.dart'; import 'package:ui/ui.dart' as ui; @@ -206,28 +205,11 @@ class EngineSceneView { } } - String _generateDebugFilename() { - final now = DateTime.now(); - final String y = now.year.toString().padLeft(4, '0'); - final String mo = now.month.toString().padLeft(2, '0'); - final String d = now.day.toString().padLeft(2, '0'); - final String h = now.hour.toString().padLeft(2, '0'); - final String mi = now.minute.toString().padLeft(2, '0'); - final String s = now.second.toString().padLeft(2, '0'); - return 'flutter-scene-$y-$mo-$d-$h-$mi-$s.json'; - } - - void dumpDebugInfo() { + Map? dumpDebugInfo() { if (kDebugMode && _previousRender != null) { - final Map debugJson = _previousRender!.scene.debugJsonDescription; - final String jsonString = jsonEncode(debugJson); - final blob = createDomBlob([jsonString], {'type': 'application/json'}); - final url = domWindow.URL.createObjectURL(blob); - final element = domDocument.createElement('a'); - element.setAttribute('href', url); - element.setAttribute('download', _generateDebugFilename()); - element.click(); + return _previousRender!.scene.debugJsonDescription; } + return null; } } diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/raw/skwasm_module.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/raw/skwasm_module.dart index fe45e99cacc..5921b47d18f 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/raw/skwasm_module.dart +++ b/engine/src/flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/raw/skwasm_module.dart @@ -28,3 +28,6 @@ external bool skwasmIsMultiThreaded(); @Native(symbol: 'skwasm_isHeavy', isLeaf: true) external bool skwasmIsHeavy(); + +@Native)>(symbol: 'skwasm_getLiveObjectCounts', isLeaf: true) +external void skwasmGetLiveObjectCounts(Pointer objectCounts); diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/renderer.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/renderer.dart index c067820604e..ea07ea716a0 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/renderer.dart +++ b/engine/src/flutter/lib/web_ui/lib/src/engine/skwasm/skwasm_impl/renderer.dart @@ -3,6 +3,8 @@ // found in the LICENSE file. import 'dart:async'; +import 'dart:convert'; +import 'dart:ffi'; import 'dart:js_interop'; import 'dart:math' as math; import 'dart:typed_data'; @@ -488,10 +490,74 @@ class SkwasmRenderer implements Renderer { ); } + String _generateDebugFilename(String filePrefix) { + final now = DateTime.now(); + final String y = now.year.toString().padLeft(4, '0'); + final String mo = now.month.toString().padLeft(2, '0'); + final String d = now.day.toString().padLeft(2, '0'); + final String h = now.hour.toString().padLeft(2, '0'); + final String mi = now.minute.toString().padLeft(2, '0'); + final String s = now.second.toString().padLeft(2, '0'); + return '$filePrefix-$y-$mo-$d-$h-$mi-$s.json'; + } + + void _dumpDebugInfo(String filePrefix, Map json) { + final String jsonString = const JsonEncoder.withIndent(' ').convert(json); + final blob = createDomBlob([jsonString], {'type': 'application/json'}); + final url = domWindow.URL.createObjectURL(blob); + final element = domDocument.createElement('a'); + element.setAttribute('href', url); + element.setAttribute('download', _generateDebugFilename(filePrefix)); + element.click(); + } + @override void dumpDebugInfo() { - for (final view in _sceneViews.values) { - view.dumpDebugInfo(); + if (kDebugMode) { + withStackScope((StackScope scope) { + final Pointer counts = scope.allocUint32Array(28); + skwasmGetLiveObjectCounts(counts); + final Map countsJson = { + 'lineBreakBufferCount': counts[0], + 'unicodePositionBufferCount': counts[1], + 'lineMetricsCount': counts[2], + 'textBoxListCount': counts[3], + 'paragraphBuilderCount': counts[4], + 'paragraphCount': counts[5], + 'strutStyleCount': counts[6], + 'textStyleCount': counts[7], + 'animatedImageCount': counts[8], + 'countourMeasureIterCount': counts[9], + 'countourMeasureCount': counts[10], + 'dataCount': counts[11], + 'colorFilterCount': counts[12], + 'imageFilterCount': counts[13], + 'maskFilterCount': counts[14], + 'typefaceCount': counts[15], + 'fontCollectionCount': counts[16], + 'imageCount': counts[17], + 'paintCount': counts[18], + 'pathCount': counts[19], + 'pictureCount': counts[20], + 'pictureRecorderCount': counts[21], + 'shaderCount': counts[22], + 'runtimeEffectCount': counts[23], + 'stringCount': counts[24], + 'string16Count': counts[25], + 'surfaceCount': counts[26], + 'verticesCount': counts[27], + }; + _dumpDebugInfo('live_object_counts', countsJson); + }); + + int i = 0; + for (final view in _sceneViews.values) { + final Map? debugJson = view.dumpDebugInfo(); + if (debugJson != null) { + _dumpDebugInfo('flutter-scene$i', debugJson); + i++; + } + } } } } diff --git a/engine/src/flutter/lib/web_ui/skwasm/BUILD.gn b/engine/src/flutter/lib/web_ui/skwasm/BUILD.gn index 850c24f081f..d5a875cf8ce 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/BUILD.gn +++ b/engine/src/flutter/lib/web_ui/skwasm/BUILD.gn @@ -17,6 +17,8 @@ template("skwasm_variant") { "fonts.cpp", "helpers.h", "image.cpp", + "live_objects.cpp", + "live_objects.h", "paint.cpp", "path.cpp", "picture.cpp", diff --git a/engine/src/flutter/lib/web_ui/skwasm/animated_image.cpp b/engine/src/flutter/lib/web_ui/skwasm/animated_image.cpp index f61507c30e8..a1ea2d67e0e 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/animated_image.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/animated_image.cpp @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "export.h" +#include "live_objects.h" #include "skwasm_support.h" #include "third_party/skia/include/android/SkAnimatedImage.h" @@ -28,6 +29,7 @@ std::unique_ptr getCodecForData(SkData* data) { SKWASM_EXPORT SkAnimatedImage* animatedImage_create(SkData* data, int targetWidth, int targetHeight) { + liveAnimatedImageCount++; auto codec = getCodecForData(data); if (!codec) { printf("Failed to create codec for animated image.\n"); @@ -52,6 +54,7 @@ SKWASM_EXPORT SkAnimatedImage* animatedImage_create(SkData* data, } SKWASM_EXPORT void animatedImage_dispose(SkAnimatedImage* image) { + liveAnimatedImageCount--; image->unref(); } @@ -73,5 +76,6 @@ SKWASM_EXPORT void animatedImage_decodeNextFrame(SkAnimatedImage* image) { } SKWASM_EXPORT SkImage* animatedImage_getCurrentFrame(SkAnimatedImage* image) { + liveImageCount++; return image->getCurrentFrame().release(); } diff --git a/engine/src/flutter/lib/web_ui/skwasm/contour_measure.cpp b/engine/src/flutter/lib/web_ui/skwasm/contour_measure.cpp index 4af486ffe3d..d8abb1f2c18 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/contour_measure.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/contour_measure.cpp @@ -4,6 +4,7 @@ #include "export.h" #include "helpers.h" +#include "live_objects.h" #include "third_party/skia/include/core/SkContourMeasure.h" #include "third_party/skia/include/core/SkPath.h" @@ -12,6 +13,7 @@ using namespace Skwasm; SKWASM_EXPORT SkContourMeasureIter* contourMeasureIter_create(SkPath* path, bool forceClosed, SkScalar resScale) { + liveCountourMeasureIterCount++; return new SkContourMeasureIter(*path, forceClosed, resScale); } @@ -19,16 +21,19 @@ SKWASM_EXPORT SkContourMeasure* contourMeasureIter_next( SkContourMeasureIter* iter) { auto next = iter->next(); if (next) { + liveCountourMeasureCount++; next->ref(); } return next.get(); } SKWASM_EXPORT void contourMeasureIter_dispose(SkContourMeasureIter* iter) { + liveCountourMeasureIterCount--; delete iter; } SKWASM_EXPORT void contourMeasure_dispose(SkContourMeasure* measure) { + liveCountourMeasureCount--; measure->unref(); } @@ -56,5 +61,6 @@ SKWASM_EXPORT SkPath* contourMeasure_getSegment(SkContourMeasure* measure, delete outPath; return nullptr; } + livePathCount++; return outPath; } diff --git a/engine/src/flutter/lib/web_ui/skwasm/data.cpp b/engine/src/flutter/lib/web_ui/skwasm/data.cpp index 1f1b9b748aa..d230fcbb44f 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/data.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/data.cpp @@ -3,10 +3,12 @@ // found in the LICENSE file. #include "export.h" +#include "live_objects.h" #include "third_party/skia/include/core/SkData.h" SKWASM_EXPORT SkData* skData_create(size_t size) { + liveDataCount++; return SkData::MakeUninitialized(size).release(); } @@ -23,5 +25,6 @@ SKWASM_EXPORT size_t skData_getSize(SkData* data) { } SKWASM_EXPORT void skData_dispose(SkData* data) { + liveDataCount--; return data->unref(); } diff --git a/engine/src/flutter/lib/web_ui/skwasm/filters.cpp b/engine/src/flutter/lib/web_ui/skwasm/filters.cpp index d50763ead09..e68554544b2 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/filters.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/filters.cpp @@ -4,6 +4,7 @@ #include "export.h" #include "helpers.h" +#include "live_objects.h" #include "third_party/skia/include/core/SkColorFilter.h" #include "third_party/skia/include/core/SkMaskFilter.h" @@ -14,21 +15,25 @@ using namespace Skwasm; SKWASM_EXPORT SkImageFilter* imageFilter_createBlur(SkScalar sigmaX, SkScalar sigmaY, SkTileMode tileMode) { + liveImageFilterCount++; return SkImageFilters::Blur(sigmaX, sigmaY, tileMode, nullptr).release(); } SKWASM_EXPORT SkImageFilter* imageFilter_createDilate(SkScalar radiusX, SkScalar radiusY) { + liveImageFilterCount++; return SkImageFilters::Dilate(radiusX, radiusY, nullptr).release(); } SKWASM_EXPORT SkImageFilter* imageFilter_createErode(SkScalar radiusX, SkScalar radiusY) { + liveImageFilterCount++; return SkImageFilters::Erode(radiusX, radiusY, nullptr).release(); } SKWASM_EXPORT SkImageFilter* imageFilter_createMatrix(SkScalar* matrix33, FilterQuality quality) { + liveImageFilterCount++; return SkImageFilters::MatrixTransform(createMatrix(matrix33), samplingOptionsForQuality(quality), nullptr) @@ -37,18 +42,22 @@ SKWASM_EXPORT SkImageFilter* imageFilter_createMatrix(SkScalar* matrix33, SKWASM_EXPORT SkImageFilter* imageFilter_createFromColorFilter( SkColorFilter* filter) { + liveImageFilterCount++; return SkImageFilters::ColorFilter(sk_ref_sp(filter), nullptr) .release(); } SKWASM_EXPORT SkImageFilter* imageFilter_compose(SkImageFilter* outer, SkImageFilter* inner) { + liveImageFilterCount++; + return SkImageFilters::Compose(sk_ref_sp(outer), sk_ref_sp(inner)) .release(); } SKWASM_EXPORT void imageFilter_dispose(SkImageFilter* filter) { + liveImageFilterCount--; filter->unref(); } @@ -62,39 +71,47 @@ SKWASM_EXPORT void imageFilter_getFilterBounds(SkImageFilter* filter, SKWASM_EXPORT SkColorFilter* colorFilter_createMode(SkColor color, SkBlendMode mode) { + liveColorFilterCount++; return SkColorFilters::Blend(color, mode).release(); } SKWASM_EXPORT SkColorFilter* colorFilter_createMatrix( float* matrixData // 20 values ) { + liveColorFilterCount++; return SkColorFilters::Matrix(matrixData).release(); } SKWASM_EXPORT SkColorFilter* colorFilter_createSRGBToLinearGamma() { + liveColorFilterCount++; return SkColorFilters::SRGBToLinearGamma().release(); } SKWASM_EXPORT SkColorFilter* colorFilter_createLinearToSRGBGamma() { + liveColorFilterCount++; return SkColorFilters::LinearToSRGBGamma().release(); } SKWASM_EXPORT SkColorFilter* colorFilter_compose(SkColorFilter* outer, SkColorFilter* inner) { + liveColorFilterCount++; return SkColorFilters::Compose(sk_ref_sp(outer), sk_ref_sp(inner)) .release(); } SKWASM_EXPORT void colorFilter_dispose(SkColorFilter* filter) { + liveColorFilterCount--; filter->unref(); } SKWASM_EXPORT SkMaskFilter* maskFilter_createBlur(SkBlurStyle blurStyle, SkScalar sigma) { + liveMaskFilterCount++; return SkMaskFilter::MakeBlur(blurStyle, sigma).release(); } SKWASM_EXPORT void maskFilter_dispose(SkMaskFilter* filter) { + liveMaskFilterCount--; filter->unref(); } diff --git a/engine/src/flutter/lib/web_ui/skwasm/fonts.cpp b/engine/src/flutter/lib/web_ui/skwasm/fonts.cpp index e8e3e4d5eab..11b3caacee2 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/fonts.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/fonts.cpp @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "export.h" +#include "live_objects.h" #include "third_party/skia/include/core/SkFontMgr.h" #include "third_party/skia/include/ports/SkFontMgr_empty.h" #include "third_party/skia/modules/skparagraph/include/FontCollection.h" @@ -15,6 +16,7 @@ using namespace skia::textlayout; using namespace Skwasm; SKWASM_EXPORT FlutterFontCollection* fontCollection_create() { + liveFontCollectionCount++; auto collection = sk_make_sp(); auto provider = sk_make_sp(); collection->enableFontFallback(); @@ -26,6 +28,7 @@ SKWASM_EXPORT FlutterFontCollection* fontCollection_create() { } SKWASM_EXPORT void fontCollection_dispose(FlutterFontCollection* collection) { + liveFontCollectionCount--; delete collection; } @@ -35,11 +38,13 @@ static sk_sp default_fontmgr() { } SKWASM_EXPORT SkTypeface* typeface_create(SkData* fontData) { + liveTypefaceCount++; auto typeface = default_fontmgr()->makeFromData(sk_ref_sp(fontData)); return typeface.release(); } SKWASM_EXPORT void typeface_dispose(SkTypeface* typeface) { + liveTypefaceCount--; typeface->unref(); } diff --git a/engine/src/flutter/lib/web_ui/skwasm/image.cpp b/engine/src/flutter/lib/web_ui/skwasm/image.cpp index 5fe04b5c0f9..2c22fb0d18d 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/image.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/image.cpp @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "export.h" +#include "live_objects.h" #include "skwasm_support.h" #include "surface.h" #include "wrappers.h" @@ -116,6 +117,7 @@ class TextureSourceImageGenerator : public GrExternalTextureGenerator { SKWASM_EXPORT SkImage* image_createFromPicture(SkPicture* picture, int32_t width, int32_t height) { + liveImageCount++; return DeferredFromPicture(sk_ref_sp(picture), {width, height}, nullptr, nullptr, BitDepth::kU8, SkColorSpace::MakeSRGB()) @@ -127,6 +129,7 @@ SKWASM_EXPORT SkImage* image_createFromPixels(SkData* data, int height, PixelFormat pixelFormat, size_t rowByteCount) { + liveImageCount++; return SkImages::RasterFromData( SkImageInfo::Make(width, height, colorTypeForPixelFormat(pixelFormat), @@ -140,6 +143,7 @@ SKWASM_EXPORT SkImage* image_createFromTextureSource(SkwasmObject textureSource, int width, int height, Skwasm::Surface* surface) { + liveImageCount++; return SkImages::DeferredFromTextureGenerator( std::unique_ptr( new TextureSourceImageGenerator( @@ -151,10 +155,12 @@ SKWASM_EXPORT SkImage* image_createFromTextureSource(SkwasmObject textureSource, } SKWASM_EXPORT void image_ref(SkImage* image) { + liveImageCount++; image->ref(); } SKWASM_EXPORT void image_dispose(SkImage* image) { + liveImageCount--; image->unref(); } diff --git a/engine/src/flutter/lib/web_ui/skwasm/live_objects.cpp b/engine/src/flutter/lib/web_ui/skwasm/live_objects.cpp new file mode 100644 index 00000000000..e964657752d --- /dev/null +++ b/engine/src/flutter/lib/web_ui/skwasm/live_objects.cpp @@ -0,0 +1,96 @@ +#include "live_objects.h" + +#include "export.h" + +uint32_t liveLineBreakBufferCount = 0; +uint32_t liveUnicodePositionBufferCount = 0; +uint32_t liveLineMetricsCount = 0; +uint32_t liveTextBoxListCount = 0; +uint32_t liveParagraphBuilderCount = 0; +uint32_t liveParagraphCount = 0; +uint32_t liveStrutStyleCount = 0; +uint32_t liveTextStyleCount = 0; +uint32_t liveAnimatedImageCount = 0; +uint32_t liveCountourMeasureIterCount = 0; +uint32_t liveCountourMeasureCount = 0; +uint32_t liveDataCount = 0; +uint32_t liveColorFilterCount = 0; +uint32_t liveImageFilterCount = 0; +uint32_t liveMaskFilterCount = 0; +uint32_t liveTypefaceCount = 0; +uint32_t liveFontCollectionCount = 0; +uint32_t liveImageCount = 0; +uint32_t livePaintCount = 0; +uint32_t livePathCount = 0; +uint32_t livePictureCount = 0; +uint32_t livePictureRecorderCount = 0; +uint32_t liveShaderCount = 0; +uint32_t liveRuntimeEffectCount = 0; +uint32_t liveStringCount = 0; +uint32_t liveString16Count = 0; +uint32_t liveSurfaceCount = 0; +uint32_t liveVerticesCount = 0; + +namespace { +struct LiveObjectCounts { + uint32_t lineBreakBufferCount; + uint32_t unicodePositionBufferCount; + uint32_t lineMetricsCount; + uint32_t textBoxListCount; + uint32_t paragraphBuilderCount; + uint32_t paragraphCount; + uint32_t strutStyleCount; + uint32_t textStyleCount; + uint32_t animatedImageCount; + uint32_t countourMeasureIterCount; + uint32_t countourMeasureCount; + uint32_t dataCount; + uint32_t colorFilterCount; + uint32_t imageFilterCount; + uint32_t maskFilterCount; + uint32_t typefaceCount; + uint32_t fontCollectionCount; + uint32_t imageCount; + uint32_t paintCount; + uint32_t pathCount; + uint32_t pictureCount; + uint32_t pictureRecorderCount; + uint32_t shaderCount; + uint32_t runtimeEffectCount; + uint32_t stringCount; + uint32_t string16Count; + uint32_t surfaceCount; + uint32_t verticesCount; +}; +} // namespace + +SKWASM_EXPORT void skwasm_getLiveObjectCounts(LiveObjectCounts* counts) { + counts->lineBreakBufferCount = liveLineBreakBufferCount; + counts->unicodePositionBufferCount = liveUnicodePositionBufferCount; + counts->lineMetricsCount = liveLineMetricsCount; + counts->textBoxListCount = liveTextBoxListCount; + counts->paragraphBuilderCount = liveParagraphBuilderCount; + counts->paragraphCount = liveParagraphCount; + counts->strutStyleCount = liveStrutStyleCount; + counts->textStyleCount = liveTextStyleCount; + counts->animatedImageCount = liveAnimatedImageCount; + counts->countourMeasureIterCount = liveCountourMeasureIterCount; + counts->countourMeasureCount = liveCountourMeasureCount; + counts->dataCount = liveDataCount; + counts->colorFilterCount = liveColorFilterCount; + counts->imageFilterCount = liveImageFilterCount; + counts->maskFilterCount = liveMaskFilterCount; + counts->typefaceCount = liveTypefaceCount; + counts->fontCollectionCount = liveFontCollectionCount; + counts->imageCount = liveImageCount; + counts->paintCount = livePaintCount; + counts->pathCount = livePathCount; + counts->pictureCount = livePictureCount; + counts->pictureRecorderCount = livePictureRecorderCount; + counts->shaderCount = liveShaderCount; + counts->runtimeEffectCount = liveRuntimeEffectCount; + counts->stringCount = liveStringCount; + counts->string16Count = liveString16Count; + counts->surfaceCount = liveSurfaceCount; + counts->verticesCount = liveVerticesCount; +} diff --git a/engine/src/flutter/lib/web_ui/skwasm/live_objects.h b/engine/src/flutter/lib/web_ui/skwasm/live_objects.h new file mode 100644 index 00000000000..9e82aec7060 --- /dev/null +++ b/engine/src/flutter/lib/web_ui/skwasm/live_objects.h @@ -0,0 +1,35 @@ +#ifndef FLUTTER_LIB_WEB_UI_SKWASM_LIVE_OBJECTS_H_ +#define FLUTTER_LIB_WEB_UI_SKWASM_LIVE_OBJECTS_H_ + +#include + +extern uint32_t liveLineBreakBufferCount; +extern uint32_t liveUnicodePositionBufferCount; +extern uint32_t liveLineMetricsCount; +extern uint32_t liveTextBoxListCount; +extern uint32_t liveParagraphBuilderCount; +extern uint32_t liveParagraphCount; +extern uint32_t liveStrutStyleCount; +extern uint32_t liveTextStyleCount; +extern uint32_t liveAnimatedImageCount; +extern uint32_t liveCountourMeasureIterCount; +extern uint32_t liveCountourMeasureCount; +extern uint32_t liveDataCount; +extern uint32_t liveColorFilterCount; +extern uint32_t liveImageFilterCount; +extern uint32_t liveMaskFilterCount; +extern uint32_t liveTypefaceCount; +extern uint32_t liveFontCollectionCount; +extern uint32_t liveImageCount; +extern uint32_t livePaintCount; +extern uint32_t livePathCount; +extern uint32_t livePictureCount; +extern uint32_t livePictureRecorderCount; +extern uint32_t liveShaderCount; +extern uint32_t liveRuntimeEffectCount; +extern uint32_t liveStringCount; +extern uint32_t liveString16Count; +extern uint32_t liveSurfaceCount; +extern uint32_t liveVerticesCount; + +#endif // FLUTTER_LIB_WEB_UI_SKWASM_LIVE_OBJECTS_H_ diff --git a/engine/src/flutter/lib/web_ui/skwasm/paint.cpp b/engine/src/flutter/lib/web_ui/skwasm/paint.cpp index 1c131a56155..1288d2b8ae4 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/paint.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/paint.cpp @@ -4,6 +4,7 @@ #include "export.h" #include "helpers.h" +#include "live_objects.h" #include "third_party/skia/include/core/SkColorFilter.h" #include "third_party/skia/include/core/SkImageFilter.h" #include "third_party/skia/include/core/SkMaskFilter.h" @@ -20,6 +21,7 @@ SKWASM_EXPORT SkPaint* paint_create(bool isAntiAlias, SkPaint::Cap strokeCap, SkPaint::Join strokeJoin, SkScalar strokeMiterLimit) { + livePaintCount++; auto paint = new SkPaint(); paint->setAntiAlias(isAntiAlias); paint->setBlendMode(blendMode); @@ -33,6 +35,7 @@ SKWASM_EXPORT SkPaint* paint_create(bool isAntiAlias, } SKWASM_EXPORT void paint_dispose(SkPaint* paint) { + livePaintCount--; delete paint; } diff --git a/engine/src/flutter/lib/web_ui/skwasm/path.cpp b/engine/src/flutter/lib/web_ui/skwasm/path.cpp index 1c8052c76e8..73d7fb31311 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/path.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/path.cpp @@ -4,6 +4,7 @@ #include "export.h" #include "helpers.h" +#include "live_objects.h" #include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkString.h" #include "third_party/skia/include/pathops/SkPathOps.h" @@ -12,14 +13,17 @@ using namespace Skwasm; SKWASM_EXPORT SkPath* path_create() { + livePathCount++; return new SkPath(); } SKWASM_EXPORT void path_dispose(SkPath* path) { + livePathCount--; delete path; } SKWASM_EXPORT SkPath* path_copy(SkPath* path) { + livePathCount++; return new SkPath(*path); } @@ -187,6 +191,7 @@ SKWASM_EXPORT void path_getBounds(SkPath* path, SkRect* rect) { SKWASM_EXPORT SkPath* path_combine(SkPathOp operation, const SkPath* path1, const SkPath* path2) { + livePathCount++; SkPath* output = new SkPath(); if (Op(*path1, *path2, operation, output)) { output->setFillType(path1->getFillType()); @@ -198,6 +203,7 @@ SKWASM_EXPORT SkPath* path_combine(SkPathOp operation, } SKWASM_EXPORT SkString* path_getSvgString(SkPath* path) { + liveStringCount++; SkString* string = new SkString(SkParsePath::ToSVGString(*path)); return string; } diff --git a/engine/src/flutter/lib/web_ui/skwasm/picture.cpp b/engine/src/flutter/lib/web_ui/skwasm/picture.cpp index aac6465cb4e..9596f1dca90 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/picture.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/picture.cpp @@ -4,6 +4,7 @@ #include "export.h" #include "helpers.h" +#include "live_objects.h" #include "third_party/skia/include/core/SkBBHFactory.h" #include "third_party/skia/include/core/SkPicture.h" #include "third_party/skia/include/core/SkPictureRecorder.h" @@ -14,10 +15,12 @@ using namespace Skwasm; SkRTreeFactory bbhFactory; SKWASM_EXPORT SkPictureRecorder* pictureRecorder_create() { + livePictureRecorderCount++; return new SkPictureRecorder(); } SKWASM_EXPORT void pictureRecorder_dispose(SkPictureRecorder* recorder) { + livePictureRecorderCount--; delete recorder; } @@ -29,6 +32,7 @@ SKWASM_EXPORT SkCanvas* pictureRecorder_beginRecording( SKWASM_EXPORT SkPicture* pictureRecorder_endRecording( SkPictureRecorder* recorder) { + livePictureCount++; return recorder->finishRecordingAsPicture().release(); } @@ -37,6 +41,7 @@ SKWASM_EXPORT void picture_getCullRect(SkPicture* picture, SkRect* outRect) { } SKWASM_EXPORT void picture_dispose(SkPicture* picture) { + livePictureCount--; picture->unref(); } diff --git a/engine/src/flutter/lib/web_ui/skwasm/shaders.cpp b/engine/src/flutter/lib/web_ui/skwasm/shaders.cpp index 18e15474705..824775f8be7 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/shaders.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/shaders.cpp @@ -4,6 +4,7 @@ #include "export.h" #include "helpers.h" +#include "live_objects.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/effects/SkGradientShader.h" #include "third_party/skia/include/effects/SkRuntimeEffect.h" @@ -19,6 +20,7 @@ SKWASM_EXPORT SkShader* shader_createLinearGradient( SkTileMode tileMode, SkScalar* matrix33 // Can be nullptr ) { + liveShaderCount++; if (matrix33) { SkMatrix localMatrix = createMatrix(matrix33); return SkGradientShader::MakeLinear(endPoints, colors, stops, count, @@ -39,6 +41,7 @@ SKWASM_EXPORT SkShader* shader_createRadialGradient(SkScalar centerX, int count, SkTileMode tileMode, SkScalar* matrix33) { + liveShaderCount++; if (matrix33) { SkMatrix localMatrix = createMatrix(matrix33); return SkGradientShader::MakeRadial({centerX, centerY}, radius, colors, @@ -60,6 +63,7 @@ SKWASM_EXPORT SkShader* shader_createConicalGradient( int count, SkTileMode tileMode, SkScalar* matrix33) { + liveShaderCount++; if (matrix33) { SkMatrix localMatrix = createMatrix(matrix33); return SkGradientShader::MakeTwoPointConical( @@ -84,6 +88,7 @@ SKWASM_EXPORT SkShader* shader_createSweepGradient(SkScalar centerX, SkScalar startAngle, SkScalar endAngle, SkScalar* matrix33) { + liveShaderCount++; if (matrix33) { SkMatrix localMatrix = createMatrix(matrix33); return SkGradientShader::MakeSweep(centerX, centerY, colors, stops, count, @@ -99,10 +104,12 @@ SKWASM_EXPORT SkShader* shader_createSweepGradient(SkScalar centerX, } SKWASM_EXPORT void shader_dispose(SkShader* shader) { + liveShaderCount--; shader->unref(); } SKWASM_EXPORT SkRuntimeEffect* runtimeEffect_create(SkString* source) { + liveRuntimeEffectCount++; auto result = SkRuntimeEffect::MakeForShader(*source); if (result.effect == nullptr) { printf("Failed to compile shader. Error text:\n%s", @@ -114,6 +121,7 @@ SKWASM_EXPORT SkRuntimeEffect* runtimeEffect_create(SkString* source) { } SKWASM_EXPORT void runtimeEffect_dispose(SkRuntimeEffect* effect) { + liveRuntimeEffectCount--; effect->unref(); } @@ -126,6 +134,7 @@ SKWASM_EXPORT SkShader* shader_createRuntimeEffectShader( SkData* uniforms, SkShader** children, size_t childCount) { + liveShaderCount++; std::vector> childPointers; for (size_t i = 0; i < childCount; i++) { childPointers.emplace_back(sk_ref_sp(children[i])); @@ -142,6 +151,7 @@ SKWASM_EXPORT SkShader* shader_createFromImage(SkImage* image, SkTileMode tileModeY, FilterQuality quality, SkScalar* matrix33) { + liveShaderCount++; if (matrix33) { SkMatrix localMatrix = createMatrix(matrix33); return image diff --git a/engine/src/flutter/lib/web_ui/skwasm/string.cpp b/engine/src/flutter/lib/web_ui/skwasm/string.cpp index 59bef9823d8..fda897164aa 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/string.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/string.cpp @@ -3,10 +3,12 @@ // found in the LICENSE file. #include "export.h" +#include "live_objects.h" #include "third_party/skia/include/core/SkString.h" SKWASM_EXPORT SkString* skString_allocate(size_t length) { + liveStringCount++; return new SkString(length); } @@ -19,10 +21,12 @@ SKWASM_EXPORT int skString_getLength(SkString* string) { } SKWASM_EXPORT void skString_free(SkString* string) { + liveStringCount--; return delete string; } SKWASM_EXPORT std::u16string* skString16_allocate(size_t length) { + liveString16Count++; std::u16string* string = new std::u16string(); string->resize(length); return string; @@ -33,5 +37,6 @@ SKWASM_EXPORT char16_t* skString16_getData(std::u16string* string) { } SKWASM_EXPORT void skString16_free(std::u16string* string) { + liveString16Count--; delete string; } diff --git a/engine/src/flutter/lib/web_ui/skwasm/surface.cpp b/engine/src/flutter/lib/web_ui/skwasm/surface.cpp index cb91b10728e..2117e31d199 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/surface.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/surface.cpp @@ -5,6 +5,7 @@ #include "surface.h" #include #include +#include "live_objects.h" #include "skwasm_support.h" #include "third_party/skia/include/gpu/ganesh/GrBackendSurface.h" @@ -234,6 +235,7 @@ SkwasmObject TextureSourceWrapper::getTextureSource() { } SKWASM_EXPORT Surface* surface_create() { + liveSurfaceCount++; return new Surface(); } @@ -248,6 +250,7 @@ SKWASM_EXPORT void surface_setCallbackHandler( } SKWASM_EXPORT void surface_destroy(Surface* surface) { + liveSurfaceCount--; // Dispatch to the worker skwasm_dispatchDisposeSurface(surface->getThreadId(), surface); } diff --git a/engine/src/flutter/lib/web_ui/skwasm/text/line_metrics.cpp b/engine/src/flutter/lib/web_ui/skwasm/text/line_metrics.cpp index c163dc322de..b94bff0d72f 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/text/line_metrics.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/text/line_metrics.cpp @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "../export.h" +#include "../live_objects.h" #include "third_party/skia/modules/skparagraph/include/Paragraph.h" using namespace skia::textlayout; @@ -16,6 +17,7 @@ SKWASM_EXPORT LineMetrics* lineMetrics_create(bool hardBreak, double left, double baseline, size_t lineNumber) { + liveLineMetricsCount++; auto metrics = new LineMetrics(); metrics->fHardBreak = hardBreak; metrics->fAscent = ascent; @@ -30,6 +32,7 @@ SKWASM_EXPORT LineMetrics* lineMetrics_create(bool hardBreak, } SKWASM_EXPORT void lineMetrics_dispose(LineMetrics* metrics) { + liveLineMetricsCount--; delete metrics; } diff --git a/engine/src/flutter/lib/web_ui/skwasm/text/paragraph.cpp b/engine/src/flutter/lib/web_ui/skwasm/text/paragraph.cpp index 0b94bdc03ba..1d96c7e0ae2 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/text/paragraph.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/text/paragraph.cpp @@ -4,6 +4,7 @@ #include "third_party/skia/modules/skparagraph/include/Paragraph.h" #include "../export.h" +#include "../live_objects.h" #include "DartTypes.h" #include "TextStyle.h" #include "include/core/SkScalar.h" @@ -11,6 +12,7 @@ using namespace skia::textlayout; SKWASM_EXPORT void paragraph_dispose(Paragraph* paragraph) { + liveParagraphCount--; delete paragraph; } @@ -125,6 +127,7 @@ SKWASM_EXPORT int paragraph_getLineNumberAt(Paragraph* paragraph, SKWASM_EXPORT LineMetrics* paragraph_getLineMetricsAtIndex(Paragraph* paragraph, size_t lineNumber) { + liveLineMetricsCount++; auto metrics = new LineMetrics(); if (paragraph->getLineMetricsAt(lineNumber, metrics)) { return metrics; @@ -139,6 +142,7 @@ struct TextBoxList { }; SKWASM_EXPORT void textBoxList_dispose(TextBoxList* list) { + liveTextBoxListCount--; delete list; } @@ -160,12 +164,14 @@ SKWASM_EXPORT TextBoxList* paragraph_getBoxesForRange( int end, RectHeightStyle heightStyle, RectWidthStyle widthStyle) { + liveTextBoxListCount++; return new TextBoxList{ paragraph->getRectsForRange(start, end, heightStyle, widthStyle)}; } SKWASM_EXPORT TextBoxList* paragraph_getBoxesForPlaceholders( Paragraph* paragraph) { + liveTextBoxListCount++; return new TextBoxList{paragraph->getRectsForPlaceholders()}; } diff --git a/engine/src/flutter/lib/web_ui/skwasm/text/paragraph_builder.cpp b/engine/src/flutter/lib/web_ui/skwasm/text/paragraph_builder.cpp index d638f3e5b23..3cf25b12b0a 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/text/paragraph_builder.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/text/paragraph_builder.cpp @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "../export.h" +#include "../live_objects.h" #include "../wrappers.h" #include "third_party/skia/modules/skparagraph/include/ParagraphBuilder.h" #include "third_party/skia/modules/skunicode/include/SkUnicode_client.h" @@ -11,6 +12,7 @@ using namespace skia::textlayout; using namespace Skwasm; SKWASM_EXPORT void paragraphBuilder_dispose(ParagraphBuilder* builder) { + liveParagraphBuilderCount--; delete builder; } @@ -48,6 +50,7 @@ SKWASM_EXPORT void paragraphBuilder_pop(ParagraphBuilder* builder) { SKWASM_EXPORT std::vector* unicodePositionBuffer_create( size_t length) { + liveUnicodePositionBufferCount++; return new std::vector(length); } @@ -58,11 +61,13 @@ SKWASM_EXPORT SkUnicode::Position* unicodePositionBuffer_getDataPointer( SKWASM_EXPORT void unicodePositionBuffer_free( std::vector* buffer) { + liveUnicodePositionBufferCount--; delete buffer; } SKWASM_EXPORT std::vector* lineBreakBuffer_create( size_t length) { + liveLineBreakBufferCount++; return new std::vector( length, {0, SkUnicode::LineBreakType::kSoftLineBreak}); } @@ -74,5 +79,6 @@ SKWASM_EXPORT SkUnicode::LineBreakBefore* lineBreakBuffer_getDataPointer( SKWASM_EXPORT void lineBreakBuffer_free( std::vector* buffer) { + liveLineBreakBufferCount--; delete buffer; } diff --git a/engine/src/flutter/lib/web_ui/skwasm/text/paragraph_builder_builtin_icu.cpp b/engine/src/flutter/lib/web_ui/skwasm/text/paragraph_builder_builtin_icu.cpp index bccc1c3b291..e31ddef45d9 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/text/paragraph_builder_builtin_icu.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/text/paragraph_builder_builtin_icu.cpp @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "../export.h" +#include "../live_objects.h" #include "../wrappers.h" #include "modules/skunicode/include/SkUnicode_icu.h" #include "third_party/skia/modules/skparagraph/include/ParagraphBuilder.h" @@ -17,12 +18,14 @@ SKWASM_EXPORT bool skwasm_isHeavy() { SKWASM_EXPORT ParagraphBuilder* paragraphBuilder_create( ParagraphStyle* style, FlutterFontCollection* collection) { + liveParagraphBuilderCount++; return ParagraphBuilder::make(*style, collection->collection, SkUnicodes::ICU::Make()) .release(); } SKWASM_EXPORT Paragraph* paragraphBuilder_build(ParagraphBuilder* builder) { + liveParagraphCount++; return builder->Build().release(); } diff --git a/engine/src/flutter/lib/web_ui/skwasm/text/paragraph_builder_client_icu.cpp b/engine/src/flutter/lib/web_ui/skwasm/text/paragraph_builder_client_icu.cpp index a157afc10ac..5dfcb7b10e1 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/text/paragraph_builder_client_icu.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/text/paragraph_builder_client_icu.cpp @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "../export.h" +#include "../live_objects.h" #include "../wrappers.h" #include "third_party/skia/modules/skparagraph/include/ParagraphBuilder.h" #include "third_party/skia/modules/skunicode/include/SkUnicode_client.h" @@ -17,11 +18,13 @@ SKWASM_EXPORT bool skwasm_isHeavy() { SKWASM_EXPORT ParagraphBuilder* paragraphBuilder_create( ParagraphStyle* style, FlutterFontCollection* collection) { + liveParagraphBuilderCount++; return ParagraphBuilder::make(*style, collection->collection, nullptr) .release(); } SKWASM_EXPORT Paragraph* paragraphBuilder_build(ParagraphBuilder* builder) { + liveParagraphCount++; auto [words, graphemeBreaks, lineBreaks] = builder->getClientICUData(); auto text = builder->getText(); sk_sp clientICU = diff --git a/engine/src/flutter/lib/web_ui/skwasm/text/strut_style.cpp b/engine/src/flutter/lib/web_ui/skwasm/text/strut_style.cpp index 6d1de9b44cb..32de4f02abe 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/text/strut_style.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/text/strut_style.cpp @@ -3,17 +3,20 @@ // found in the LICENSE file. #include "../export.h" +#include "../live_objects.h" #include "third_party/skia/modules/skparagraph/include/Paragraph.h" using namespace skia::textlayout; SKWASM_EXPORT StrutStyle* strutStyle_create() { + liveStrutStyleCount++; auto style = new StrutStyle(); style->setStrutEnabled(true); return style; } SKWASM_EXPORT void strutStyle_dispose(StrutStyle* style) { + liveStrutStyleCount--; delete style; } diff --git a/engine/src/flutter/lib/web_ui/skwasm/text/text_style.cpp b/engine/src/flutter/lib/web_ui/skwasm/text/text_style.cpp index 06171a25595..32585589082 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/text/text_style.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/text/text_style.cpp @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "../export.h" +#include "../live_objects.h" #include "../wrappers.h" #include "third_party/skia/modules/skparagraph/include/Paragraph.h" @@ -12,6 +13,7 @@ using namespace skia::textlayout; using namespace Skwasm; SKWASM_EXPORT TextStyle* textStyle_create() { + liveTextStyleCount++; auto style = new TextStyle(); // Default color in flutter is black. @@ -20,10 +22,12 @@ SKWASM_EXPORT TextStyle* textStyle_create() { } SKWASM_EXPORT TextStyle* textStyle_copy(TextStyle* style) { + liveTextStyleCount++; return new TextStyle(*style); } SKWASM_EXPORT void textStyle_dispose(TextStyle* style) { + liveTextStyleCount--; delete style; } diff --git a/engine/src/flutter/lib/web_ui/skwasm/vertices.cpp b/engine/src/flutter/lib/web_ui/skwasm/vertices.cpp index caf187f1c7e..2490653902f 100644 --- a/engine/src/flutter/lib/web_ui/skwasm/vertices.cpp +++ b/engine/src/flutter/lib/web_ui/skwasm/vertices.cpp @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "export.h" +#include "live_objects.h" #include "third_party/skia/include/core/SkVertices.h" @@ -13,11 +14,13 @@ SKWASM_EXPORT SkVertices* vertices_create(SkVertices::VertexMode vertexMode, SkColor* colors, int indexCount, uint16_t* indices) { + liveVerticesCount++; return SkVertices::MakeCopy(vertexMode, vertexCount, positions, textureCoordinates, colors, indexCount, indices) .release(); } SKWASM_EXPORT void vertices_dispose(SkVertices* vertices) { + liveVerticesCount--; vertices->unref(); }