forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Impeller] Add GPUTracer for impeller metal backend (flutter#36499)
- Loading branch information
Showing
11 changed files
with
249 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#pragma once | ||
|
||
#include <Metal/Metal.h> | ||
|
||
#include "flutter/fml/macros.h" | ||
#include "impeller/base/backend_cast.h" | ||
#include "impeller/renderer/gpu_tracer.h" | ||
|
||
namespace impeller { | ||
|
||
class GPUTracerMTL final : public GPUTracer, | ||
public BackendCast<GPUTracerMTL, GPUTracer> { | ||
public: | ||
// |GPUTracer| | ||
~GPUTracerMTL() override; | ||
|
||
// |GPUTracer| | ||
bool StartCapturingFrame(GPUTracerConfiguration configuration) override; | ||
|
||
// |GPUTracer| | ||
bool StopCapturingFrame() override; | ||
|
||
private: | ||
friend class ContextMTL; | ||
|
||
id<MTLDevice> device_; | ||
GPUTracerMTL(id<MTLDevice> device); | ||
|
||
NSURL* GetUniqueGPUTraceSavedURL() const; | ||
NSURL* GetGPUTraceSavedDictionaryURL() const; | ||
bool CreateGPUTraceSavedDictionaryIfNeeded() const; | ||
|
||
FML_DISALLOW_COPY_AND_ASSIGN(GPUTracerMTL); | ||
}; | ||
|
||
} // namespace impeller |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "impeller/renderer/backend/metal/gpu_tracer_mtl.h" | ||
#include <fml/logging.h> | ||
|
||
namespace impeller { | ||
|
||
GPUTracerMTL::GPUTracerMTL(id<MTLDevice> device) : device_(device) {} | ||
|
||
GPUTracerMTL::~GPUTracerMTL() = default; | ||
|
||
bool GPUTracerMTL::StartCapturingFrame(GPUTracerConfiguration configuration) { | ||
if (!device_) { | ||
return false; | ||
} | ||
|
||
MTLCaptureManager* captureManager = [MTLCaptureManager sharedCaptureManager]; | ||
if (captureManager.isCapturing) { | ||
return false; | ||
} | ||
|
||
if (@available(iOS 13.0, macOS 10.15, *)) { | ||
MTLCaptureDescriptor* desc = [[MTLCaptureDescriptor alloc] init]; | ||
desc.captureObject = device_; | ||
|
||
MTLCaptureDestination targetDestination = | ||
configuration.mtl_frame_capture_save_trace_as_document | ||
? MTLCaptureDestinationGPUTraceDocument | ||
: MTLCaptureDestinationDeveloperTools; | ||
if (![captureManager supportsDestination:targetDestination]) { | ||
return false; | ||
} | ||
desc.destination = targetDestination; | ||
|
||
if (configuration.mtl_frame_capture_save_trace_as_document) { | ||
if (!CreateGPUTraceSavedDictionaryIfNeeded()) { | ||
return false; | ||
} | ||
NSURL* outputURL = GetUniqueGPUTraceSavedURL(); | ||
desc.outputURL = outputURL; | ||
} | ||
return [captureManager startCaptureWithDescriptor:desc error:nil]; | ||
} | ||
|
||
[captureManager startCaptureWithDevice:device_]; | ||
return captureManager.isCapturing; | ||
} | ||
|
||
bool GPUTracerMTL::StopCapturingFrame() { | ||
if (!device_) { | ||
return false; | ||
} | ||
|
||
MTLCaptureManager* captureManager = [MTLCaptureManager sharedCaptureManager]; | ||
if (!captureManager.isCapturing) { | ||
return false; | ||
} | ||
|
||
[captureManager stopCapture]; | ||
return !captureManager.isCapturing; | ||
} | ||
|
||
NSURL* GPUTracerMTL::GetUniqueGPUTraceSavedURL() const { | ||
NSURL* savedDictionaryURL = GetGPUTraceSavedDictionaryURL(); | ||
NSString* uniqueID = [NSUUID UUID].UUIDString; | ||
return [[savedDictionaryURL URLByAppendingPathComponent:uniqueID] | ||
URLByAppendingPathExtension:@"gputrace"]; | ||
} | ||
|
||
bool GPUTracerMTL::CreateGPUTraceSavedDictionaryIfNeeded() const { | ||
NSFileManager* fileManager = [NSFileManager defaultManager]; | ||
NSURL* gpuTraceSavedDictionaryURL = GetGPUTraceSavedDictionaryURL(); | ||
if ([fileManager fileExistsAtPath:gpuTraceSavedDictionaryURL.path]) { | ||
return true; | ||
} | ||
|
||
NSError* error = nil; | ||
[fileManager createDirectoryAtURL:gpuTraceSavedDictionaryURL | ||
withIntermediateDirectories:NO | ||
attributes:nil | ||
error:&error]; | ||
if (error != nil) { | ||
FML_LOG(ERROR) << "Metal frame capture " | ||
"CreateGPUTraceSavedDictionaryIfNeeded failed."; | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
NSURL* GPUTracerMTL::GetGPUTraceSavedDictionaryURL() const { | ||
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, | ||
NSUserDomainMask, YES); | ||
NSString* docPath = [paths objectAtIndex:0]; | ||
NSURL* docURL = [NSURL fileURLWithPath:docPath]; | ||
NSURL* gpuTraceDictionaryURL = | ||
[docURL URLByAppendingPathComponent:@"MetalCaptureGPUTrace"]; | ||
return gpuTraceDictionaryURL; | ||
} | ||
|
||
} // namespace impeller |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "gpu_tracer.h" | ||
|
||
namespace impeller { | ||
|
||
GPUTracer::GPUTracer() = default; | ||
|
||
GPUTracer::~GPUTracer() = default; | ||
|
||
bool GPUTracer::StartCapturingFrame(GPUTracerConfiguration configuration) { | ||
return false; | ||
} | ||
|
||
bool GPUTracer::StopCapturingFrame() { | ||
return false; | ||
} | ||
|
||
} // namespace impeller |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "flutter/fml/macros.h" | ||
|
||
namespace impeller { | ||
|
||
//------------------------------------------------------------------------------ | ||
/// @brief GPU tracer configuration. | ||
/// | ||
struct GPUTracerConfiguration { | ||
/// This param is for metal backend. | ||
/// When this value is true, a gpu trace file will be saved in devices when | ||
/// metal frame capture finishes. Otherwise, the Xcode will automatically open | ||
/// and show trace result. | ||
/// | ||
bool mtl_frame_capture_save_trace_as_document = false; | ||
}; | ||
|
||
//------------------------------------------------------------------------------ | ||
/// @brief A GPU tracer to trace gpu workflow during rendering. | ||
/// | ||
class GPUTracer { | ||
public: | ||
virtual ~GPUTracer(); | ||
|
||
//---------------------------------------------------------------------------- | ||
/// @brief Start capturing frame. This method should only be called when | ||
/// developing. | ||
/// | ||
/// @param[in] configuration The configuration passed in for capture. | ||
/// | ||
/// @return The operation successful or not. | ||
/// | ||
virtual bool StartCapturingFrame(GPUTracerConfiguration configuration); | ||
|
||
//---------------------------------------------------------------------------- | ||
/// @brief Stop capturing frame. This should only be called when | ||
/// developing. | ||
/// | ||
/// @return The operation successful or not. | ||
/// | ||
virtual bool StopCapturingFrame(); | ||
|
||
protected: | ||
GPUTracer(); | ||
|
||
private: | ||
FML_DISALLOW_COPY_AND_ASSIGN(GPUTracer); | ||
}; | ||
|
||
} // namespace impeller |