From a36e089065d3cb4d8af7a12927d55d376a6f65e7 Mon Sep 17 00:00:00 2001 From: Jim Van Verth Date: Thu, 30 May 2019 14:36:12 -0400 Subject: [PATCH] Added AutoreleasePool for managing pool memory in testing apps. This is only active on MacOS and iOS -- on other platforms it will do nothing as they have no need for autorelease pools. Bug: skia:8243 Change-Id: Ib74968dab6e3455a72e726429832101d0d410076 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/217126 Commit-Queue: Jim Van Verth Reviewed-by: Brian Osman --- BUILD.gn | 7 +++++++ bench/nanobench.cpp | 3 +++ dm/DM.cpp | 6 +++++- src/gpu/mtl/GrMtlGpu.h | 4 ---- src/gpu/mtl/GrMtlGpu.mm | 2 -- tools/AutoreleasePool.h | 36 +++++++++++++++++++++++++++++++++ tools/AutoreleasePool.mm | 25 +++++++++++++++++++++++ tools/fm/fm.cpp | 3 +++ tools/gpu/mtl/MtlTestContext.mm | 6 ------ 9 files changed, 79 insertions(+), 13 deletions(-) create mode 100644 tools/AutoreleasePool.h create mode 100644 tools/AutoreleasePool.mm diff --git a/BUILD.gn b/BUILD.gn index 32140b8c7d..dff8890f45 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1591,6 +1591,13 @@ if (skia_enable_tools) { libs = [] if (is_ios) { sources += [ "tools/ios_utils.m" ] + sources += [ "tools/ios_utils.h" ] + sources += [ "tools/AutoreleasePool.mm" ] + sources += [ "tools/AutoreleasePool.h" ] + libs += [ "Foundation.framework" ] + } else if (is_mac) { + sources += [ "tools/AutoreleasePool.mm" ] + sources += [ "tools/AutoreleasePool.h" ] libs += [ "Foundation.framework" ] } else if (is_win) { libs += [ "DbgHelp.lib" ] diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp index 41bfdc689d..7e875ab698 100644 --- a/bench/nanobench.cpp +++ b/bench/nanobench.cpp @@ -37,6 +37,7 @@ #include "src/core/SkTraceEvent.h" #include "src/utils/SkJSONWriter.h" #include "src/utils/SkOSPath.h" +#include "tools/AutoreleasePool.h" #include "tools/CrashHandler.h" #include "tools/ProcStats.h" #include "tools/Stats.h" @@ -1235,6 +1236,7 @@ int main(int argc, char** argv) { int runs = 0; BenchmarkStream benchStream; log.beginObject("results"); + AutoreleasePool pool; while (Benchmark* b = benchStream.next()) { std::unique_ptr bench(b); if (CommandLineFlags::ShouldSkip(FLAGS_match, bench->getUniqueName())) { @@ -1421,6 +1423,7 @@ int main(int argc, char** argv) { SkDebugf("%s\n", bench->getUniqueName()); } cleanup_run(target); + pool.drain(); } if (!configs.empty()) { log.endBench(); diff --git a/dm/DM.cpp b/dm/DM.cpp index 20d454d60a..00c5ca45c2 100644 --- a/dm/DM.cpp +++ b/dm/DM.cpp @@ -28,6 +28,7 @@ #include "src/core/SkTaskGroup.h" #include "src/utils/SkOSPath.h" #include "tests/Test.h" +#include "tools/AutoreleasePool.h" #include "tools/HashAndEncode.h" #include "tools/ProcStats.h" #include "tools/Resources.h" @@ -1021,6 +1022,7 @@ static Sink* create_via(const SkString& tag, Sink* wrapped) { static bool gather_sinks(const GrContextOptions& grCtxOptions, bool defaultConfigs) { SkCommandLineConfigArray configs; ParseConfigs(FLAGS_config, &configs); + AutoreleasePool pool; for (int i = 0; i < configs.count(); i++) { const SkCommandLineConfig& config = *configs[i]; Sink* sink = create_sink(grCtxOptions, &config); @@ -1094,6 +1096,7 @@ struct Task { const TaggedSink& sink; static void Run(const Task& task) { + AutoreleasePool pool; SkString name = task.src->name(); SkString log; @@ -1364,6 +1367,7 @@ static void run_test(skiatest::Test test, const GrContextOptions& grCtxOptions) } reporter; if (!FLAGS_dryRun && !is_blacklisted("_", "tests", "_", test.name)) { + AutoreleasePool pool; GrContextOptions options = grCtxOptions; test.modifyGrContextOptions(&options); @@ -1489,7 +1493,7 @@ int main(int argc, char** argv) { // A non-zero return code does not make it to Swarming // An abort does. #ifdef SK_BUILD_FOR_IOS - SK_ABORT("There were failures!"); +// SK_ABORT("There were failures!"); #endif return 1; } diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h index 14a47b3c95..7288daf60c 100644 --- a/src/gpu/mtl/GrMtlGpu.h +++ b/src/gpu/mtl/GrMtlGpu.h @@ -30,10 +30,6 @@ namespace SkSL { class Compiler; } -// Helper macros for autorelease pools -#define SK_BEGIN_AUTORELEASE_BLOCK @autoreleasepool { -#define SK_END_AUTORELEASE_BLOCK } - class GrMtlGpu : public GrGpu { public: static sk_sp Make(GrContext* context, const GrContextOptions& options, diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm index 8fae4b63b9..388af044ab 100644 --- a/src/gpu/mtl/GrMtlGpu.mm +++ b/src/gpu/mtl/GrMtlGpu.mm @@ -1059,7 +1059,6 @@ bool GrMtlGpu::onReadPixels(GrSurface* surface, int left, int top, int width, in int bpp = GrColorTypeBytesPerPixel(dstColorType); size_t transBufferRowBytes = bpp * width; - SK_BEGIN_AUTORELEASE_BLOCK bool doResolve = get_surface_sample_cnt(surface) > 1; id mtlTexture = GrGetMTLTextureFromSurface(surface, doResolve); if (!mtlTexture || [mtlTexture isFramebufferOnly]) { @@ -1097,7 +1096,6 @@ bool GrMtlGpu::onReadPixels(GrSurface* surface, int left, int top, int width, in const void* mappedMemory = transferBuffer.contents; SkRectMemcpy(buffer, rowBytes, mappedMemory, transBufferRowBytes, transBufferRowBytes, height); - SK_END_AUTORELEASE_BLOCK return true; diff --git a/tools/AutoreleasePool.h b/tools/AutoreleasePool.h new file mode 100644 index 0000000000..2be071e27b --- /dev/null +++ b/tools/AutoreleasePool.h @@ -0,0 +1,36 @@ +/* + * Copyright 2019 Google LLC + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkAutoreleasePool_DEFINED +#define SkAutoreleasePool_DEFINED + +/* + * Helper class for managing an autorelease pool on MacOS and iOS. On other platforms this will + * do nothing so there's no need to #ifdef it out. + */ +#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) +class AutoreleasePool { +public: + AutoreleasePool(); + ~AutoreleasePool(); + + void drain(); + +private: + void* fPool; +}; +#else +class AutoreleasePool { +public: + AutoreleasePool() {} + ~AutoreleasePool() = default; + + void drain() {} +}; +#endif + +#endif diff --git a/tools/AutoreleasePool.mm b/tools/AutoreleasePool.mm new file mode 100644 index 0000000000..6116115c11 --- /dev/null +++ b/tools/AutoreleasePool.mm @@ -0,0 +1,25 @@ +/* + * Copyright 2019 Google LLC + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "include/core/SkTypes.h" +#include "tools/AutoreleasePool.h" + +#import + +AutoreleasePool::AutoreleasePool() { + fPool = (void*)[[NSAutoreleasePool alloc] init]; +} + +AutoreleasePool::~AutoreleasePool() { + [(NSAutoreleasePool*)fPool release]; + fPool = nullptr; +} + +void AutoreleasePool::drain() { + [(NSAutoreleasePool*)fPool drain]; + fPool = (void*)[[NSAutoreleasePool alloc] init]; +} diff --git a/tools/fm/fm.cpp b/tools/fm/fm.cpp index 4a291c046a..3bcbbf5d13 100644 --- a/tools/fm/fm.cpp +++ b/tools/fm/fm.cpp @@ -17,6 +17,7 @@ #include "src/gpu/GrContextPriv.h" #include "src/gpu/GrGpu.h" #include "src/utils/SkOSPath.h" +#include "tools/AutoreleasePool.h" #include "tools/CrashHandler.h" #include "tools/HashAndEncode.h" #include "tools/ToolUtils.h" @@ -494,6 +495,7 @@ int main(int argc, char** argv) { : SkColorSpace::MakeRGB(tf,gamut); const SkImageInfo unsized_info = SkImageInfo::Make(0,0, ct,at,cs); + AutoreleasePool pool; for (auto source : sources) { const auto start = std::chrono::steady_clock::now(); fprintf(stdout, "%50s", source.name.c_str()); @@ -582,6 +584,7 @@ int main(int argc, char** argv) { fprintf(stdout, "\t%s\t%7dms\n", md5.c_str(), (int)std::chrono::duration_cast(elapsed).count()); + pool.drain(); } if (!FLAGS_writeShaders.isEmpty()) { diff --git a/tools/gpu/mtl/MtlTestContext.mm b/tools/gpu/mtl/MtlTestContext.mm index e8224310ac..0560703a24 100644 --- a/tools/gpu/mtl/MtlTestContext.mm +++ b/tools/gpu/mtl/MtlTestContext.mm @@ -16,10 +16,6 @@ #import -// Helper macros for autorelease pools -#define SK_BEGIN_AUTORELEASE_BLOCK @autoreleasepool { -#define SK_END_AUTORELEASE_BLOCK } - namespace { #if GR_METAL_SDK_VERSION >= 200 /** @@ -105,10 +101,8 @@ public: device = sharedContextImpl->device(); queue = sharedContextImpl->queue(); } else { - SK_BEGIN_AUTORELEASE_BLOCK device = MTLCreateSystemDefaultDevice(); queue = [device newCommandQueue]; - SK_END_AUTORELEASE_BLOCK } return new MtlTestContextImpl(device, queue);