11//
22// Copyright 2022 Apple
33//
4- // Licensed under the Apache License, Version 2.0 (the "Apache License")
5- // with the following modification; you may not use this file except in
6- // compliance with the Apache License and the following modification to it:
7- // Section 6. Trademarks. is deleted and replaced with:
8- //
9- // 6. Trademarks. This License does not grant permission to use the trade
10- // names, trademarks, service marks, or product names of the Licensor
11- // and its affiliates, except as required to comply with Section 4(c) of
12- // the License and to reproduce the content of the NOTICE file.
13- //
14- // You may obtain a copy of the Apache License at
15- //
16- // http://www.apache.org/licenses/LICENSE-2.0
17- //
18- // Unless required by applicable law or agreed to in writing, software
19- // distributed under the Apache License with the above modification is
20- // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21- // KIND, either express or implied. See the Apache License for the specific
22- // language governing permissions and limitations under the Apache License.
4+ // Licensed under the terms set forth in the LICENSE.txt file available at
5+ // https://openusd.org/license.
236//
247
258#include " pxr/pxr.h"
9+ #include " pxr/base/arch/fileSystem.h"
2610#include " pxr/base/tf/pxrCLI11/CLI11.h"
2711#include " pxr/base/tf/exception.h"
12+ #include " pxr/base/tf/mallocTag.h"
2813#include " pxr/base/tf/scoped.h"
2914#include " pxr/base/tf/stringUtils.h"
15+ #include " pxr/base/trace/collector.h"
16+ #include " pxr/base/trace/reporter.h"
3017#include " pxr/usd/sdf/layer.h"
3118#include " pxr/usd/sdf/fileFormat.h"
3219#include " pxr/usd/usdRender/pass.h"
@@ -92,7 +79,6 @@ class GLFWOpenGLContext
9279};
9380#endif
9481
95-
9682using namespace pxr_CLI ;
9783
9884struct Args {
@@ -114,8 +100,33 @@ struct Args {
114100 bool domeLightVisibility = true ;
115101 std::string rsPrimPath;
116102 std::string rpPrimPath;
103+ std::string traceToFile;
104+ std::string traceFormat;
105+ bool memstats = false ;
117106};
118107
108+ void _DumpMallocTags (UsdStageRefPtr usdStage) {
109+ if (!TfMallocTag::IsInitialized ()) {
110+ std::cout << " Unable to accumulate memory usage since the Pxr MallocTag system was not initialized" << std::endl;
111+ return ;
112+ }
113+
114+ TfMallocTag::CallTree callTree;
115+ TfMallocTag::GetCallTree (&callTree);
116+
117+ auto memInMb = TfMallocTag::GetTotalBytes ();// / (1024.0 * 1024.0);
118+
119+ auto rootLayerIdentifier = usdStage->GetRootLayer ()->GetIdentifier ();
120+ auto layerName = TfGetBaseName (rootLayerIdentifier);
121+
122+ std::string reportName = ArchMakeTmpFileName (layerName, " .mallocTag" );
123+
124+ std::ofstream os (reportName);
125+ callTree.Report (os, " " );
126+ std::cout << " Memory consumption of usdrecord for " << layerName << " is " << memInMb << " Mb" << std::endl;
127+ std::cout << " For detailed analysis, see " << reportName << std::endl;
128+ }
129+
119130// cameraArgs.py module
120131SdfPath cameraArgs_GetCameraSdfPath (const std::string &cameraPath) {
121132 // This avoids an Sdf warning if an empty string is given, which someone
@@ -501,6 +512,31 @@ static void Configure(CLI::App *app, Args &args) {
501512 " stage metadata, using this argument will override that opinion. "
502513 " Furthermore any properties authored on the RenderSettings will "
503514 " override other arguments (imageWidth, camera, outputImagePath)" );
515+
516+ app->add_option (" --traceToFile" , args.traceToFile ,
517+ " Start tracing at application startup and "
518+ " write --traceFormat specified format output to the "
519+ " specified trace file when the application quits" );
520+
521+ app->add_option (" --traceFormat" , args.traceFormat ,
522+ " Output format for trace file specified by "
523+ " --traceToFile. \' chrome\' files can be read in "
524+ " chrome, \' trace\' files are simple text reports. "
525+ " (default=chrome)" )
526+ ->default_val (" chrome" )
527+ ->check (CLI::IsMember ({" chrome" , " trace" }));
528+
529+ // TODO - determine if this this the correct way to guard presenting the command line argument
530+ // this would provide a cleaner user experience.
531+ #ifdef PXR_ARCH_SUPPORT_MALLOC_HOOKS
532+ app->add_flag (" --memstats" , args.memstats ,
533+ " Use the Pxr MallocTags memory accounting system to profile "
534+ " USD, saving results to a tmp file, with a summary to the console. "
535+ " Will have no effect if MallocTags are not supported in the "
536+ " USD installation." )
537+ ->default_val (false );
538+ #endif
539+
504540}
505541
506542static int32_t UsdRecord (const Args &args) {
@@ -519,6 +555,17 @@ static int32_t UsdRecord(const Args &args) {
519555 purposes.emplace_back (TfToken (purposeStr));
520556 }
521557
558+ if (args.memstats ) {
559+ std::string reason;
560+ if (!TfMallocTag::Initialize (&reason)) {
561+ std::cerr << " MallocTag cannot initialize : '" << reason << " '" << std::endl;
562+ }
563+ }
564+
565+ if (!args.traceToFile .empty ()) {
566+ TraceCollector::GetInstance ().SetEnabled (true );
567+ }
568+
522569 // Load the root layer.
523570 SdfLayerRefPtr rootLayer = SdfLayer::FindOrOpen (args.usdFilePath );
524571 if (!rootLayer) {
@@ -708,6 +755,25 @@ static int32_t UsdRecord(const Args &args) {
708755 // Release our reference to the frame recorder so it can be deleted before other resources are freed
709756 frameRecorder = nullptr ;
710757
758+ if (TraceCollector::GetInstance ().IsEnabled ()) {
759+ TraceCollector::GetInstance ().SetEnabled (false );
760+ if (args.traceFormat == " trace" ) {
761+ std::ofstream os (args.traceToFile , std::ios_base::out);
762+ TraceReporter::GetGlobalReporter ()->Report (os);
763+
764+ } else if (args.traceFormat == " chrome" ) {
765+ std::ofstream os (args.traceToFile , std::ios_base::out);
766+ TraceReporter::GetGlobalReporter ()->ReportChromeTracing (os);
767+
768+ } else {
769+ TF_CODING_ERROR (" Invalid trace format option provided: %s - trace/chrome are the valid options" , args.traceFormat .c_str ());
770+ }
771+ }
772+
773+ if (args.memstats ) {
774+ _DumpMallocTags (usdStage);
775+ }
776+
711777 return 0 ;
712778}
713779
0 commit comments