1/* 2 * Copyright 2022 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "src/gpu/graphite/mtl/MtlQueueManager.h" 9 10#include "src/gpu/graphite/GpuWorkSubmission.h" 11#include "src/gpu/graphite/mtl/MtlCommandBuffer.h" 12#include "src/gpu/graphite/mtl/MtlResourceProvider.h" 13#include "src/gpu/graphite/mtl/MtlSharedContext.h" 14 15namespace skgpu::graphite { 16 17MtlQueueManager::MtlQueueManager(sk_cfp<id<MTLCommandQueue>> queue, 18 const SharedContext* sharedContext) 19 : QueueManager(sharedContext) 20 , fQueue(std::move(queue)) 21{ 22} 23 24const MtlSharedContext* MtlQueueManager::mtlSharedContext() const { 25 return static_cast<const MtlSharedContext*>(fSharedContext); 26} 27 28std::unique_ptr<CommandBuffer> MtlQueueManager::getNewCommandBuffer( 29 ResourceProvider* resourceProvider, Protected) { 30 MtlResourceProvider* mtlResourceProvider = static_cast<MtlResourceProvider*>(resourceProvider); 31 auto cmdBuffer = MtlCommandBuffer::Make(fQueue.get(), 32 this->mtlSharedContext(), 33 mtlResourceProvider); 34 return cmdBuffer; 35} 36 37class MtlWorkSubmission final : public GpuWorkSubmission { 38public: 39 MtlWorkSubmission(std::unique_ptr<CommandBuffer> cmdBuffer, QueueManager* queueManager) 40 : GpuWorkSubmission(std::move(cmdBuffer), queueManager) {} 41 ~MtlWorkSubmission() override {} 42 43private: 44 bool onIsFinished(const SharedContext*) override { 45 return static_cast<MtlCommandBuffer*>(this->commandBuffer())->isFinished(); 46 } 47 void onWaitUntilFinished(const SharedContext*) override { 48 return static_cast<MtlCommandBuffer*>(this->commandBuffer())->waitUntilFinished(); 49 } 50}; 51 52QueueManager::OutstandingSubmission MtlQueueManager::onSubmitToGpu() { 53 SkASSERT(fCurrentCommandBuffer); 54 MtlCommandBuffer* mtlCmdBuffer = static_cast<MtlCommandBuffer*>(fCurrentCommandBuffer.get()); 55 if (!mtlCmdBuffer->commit()) { 56 fCurrentCommandBuffer->callFinishedProcs(/*success=*/false); 57 return nullptr; 58 } 59 60 std::unique_ptr<GpuWorkSubmission> submission( 61 new MtlWorkSubmission(std::move(fCurrentCommandBuffer), this)); 62 return submission; 63} 64 65#if defined(GPU_TEST_UTILS) 66void MtlQueueManager::startCapture() { 67 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) { 68 // TODO: add newer Metal interface as well 69 MTLCaptureManager* captureManager = [MTLCaptureManager sharedCaptureManager]; 70 if (captureManager.isCapturing) { 71 return; 72 } 73 if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { 74 MTLCaptureDescriptor* captureDescriptor = [[MTLCaptureDescriptor alloc] init]; 75 captureDescriptor.captureObject = fQueue.get(); 76 77 NSError *error; 78 if (![captureManager startCaptureWithDescriptor: captureDescriptor error:&error]) 79 { 80 NSLog(@"Failed to start capture, error %@", error); 81 } 82 } else { 83 [captureManager startCaptureWithCommandQueue: fQueue.get()]; 84 } 85 } 86} 87 88void MtlQueueManager::stopCapture() { 89 if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) { 90 MTLCaptureManager* captureManager = [MTLCaptureManager sharedCaptureManager]; 91 if (captureManager.isCapturing) { 92 [captureManager stopCapture]; 93 } 94 } 95} 96#endif 97 98} // namespace skgpu::graphite 99