1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2021 Google LLC 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "experimental/graphite/src/mtl/MtlGpu.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "experimental/graphite/src/Caps.h" 11cb93a386Sopenharmony_ci#include "experimental/graphite/src/mtl/MtlCommandBuffer.h" 12cb93a386Sopenharmony_ci#include "experimental/graphite/src/mtl/MtlResourceProvider.h" 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_cinamespace skgpu::mtl { 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_cisk_sp<skgpu::Gpu> Gpu::Make(const BackendContext& context) { 17cb93a386Sopenharmony_ci sk_cfp<id<MTLDevice>> device = sk_ret_cfp((id<MTLDevice>)(context.fDevice.get())); 18cb93a386Sopenharmony_ci sk_cfp<id<MTLCommandQueue>> queue = sk_ret_cfp((id<MTLCommandQueue>)(context.fQueue.get())); 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_ci sk_sp<const Caps> caps(new Caps(device.get())); 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_ci return sk_sp<skgpu::Gpu>(new Gpu(std::move(device), std::move(queue), std::move(caps))); 23cb93a386Sopenharmony_ci} 24cb93a386Sopenharmony_ci 25cb93a386Sopenharmony_ciGpu::Gpu(sk_cfp<id<MTLDevice>> device, sk_cfp<id<MTLCommandQueue>> queue, sk_sp<const Caps> caps) 26cb93a386Sopenharmony_ci : skgpu::Gpu(std::move(caps)) 27cb93a386Sopenharmony_ci , fDevice(std::move(device)) 28cb93a386Sopenharmony_ci , fQueue(std::move(queue)) { 29cb93a386Sopenharmony_ci fResourceProvider.reset(new ResourceProvider(this)); 30cb93a386Sopenharmony_ci} 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ciGpu::~Gpu() { 33cb93a386Sopenharmony_ci} 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_ciclass WorkSubmission final : public skgpu::GpuWorkSubmission { 36cb93a386Sopenharmony_cipublic: 37cb93a386Sopenharmony_ci WorkSubmission(sk_sp<CommandBuffer> cmdBuffer) 38cb93a386Sopenharmony_ci : fCommandBuffer(std::move(cmdBuffer)) {} 39cb93a386Sopenharmony_ci ~WorkSubmission() override {} 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ci bool isFinished() override { 42cb93a386Sopenharmony_ci return fCommandBuffer->isFinished(); 43cb93a386Sopenharmony_ci } 44cb93a386Sopenharmony_ci void waitUntilFinished(const skgpu::Gpu*) override { 45cb93a386Sopenharmony_ci return fCommandBuffer->waitUntilFinished(); 46cb93a386Sopenharmony_ci } 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_ciprivate: 49cb93a386Sopenharmony_ci sk_sp<CommandBuffer> fCommandBuffer; 50cb93a386Sopenharmony_ci}; 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_cibool Gpu::onSubmit(sk_sp<skgpu::CommandBuffer> commandBuffer) { 53cb93a386Sopenharmony_ci SkASSERT(commandBuffer); 54cb93a386Sopenharmony_ci sk_sp<CommandBuffer>& mtlCmdBuffer = (sk_sp<CommandBuffer>&)(commandBuffer); 55cb93a386Sopenharmony_ci if (!mtlCmdBuffer->commit()) { 56cb93a386Sopenharmony_ci return false; 57cb93a386Sopenharmony_ci } 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_ci std::unique_ptr<WorkSubmission> submission(new WorkSubmission(mtlCmdBuffer)); 60cb93a386Sopenharmony_ci new (fOutstandingSubmissions.push_back()) OutstandingSubmission(std::move(submission)); 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_ci return true; 63cb93a386Sopenharmony_ci} 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci#if GRAPHITE_TEST_UTILS 66cb93a386Sopenharmony_civoid Gpu::testingOnly_startCapture() { 67cb93a386Sopenharmony_ci if (@available(macOS 10.13, iOS 11.0, *)) { 68cb93a386Sopenharmony_ci // TODO: add newer Metal interface as well 69cb93a386Sopenharmony_ci MTLCaptureManager* captureManager = [MTLCaptureManager sharedCaptureManager]; 70cb93a386Sopenharmony_ci if (captureManager.isCapturing) { 71cb93a386Sopenharmony_ci return; 72cb93a386Sopenharmony_ci } 73cb93a386Sopenharmony_ci if (@available(macOS 10.15, iOS 13.0, *)) { 74cb93a386Sopenharmony_ci MTLCaptureDescriptor* captureDescriptor = [[MTLCaptureDescriptor alloc] init]; 75cb93a386Sopenharmony_ci captureDescriptor.captureObject = fQueue.get(); 76cb93a386Sopenharmony_ci 77cb93a386Sopenharmony_ci NSError *error; 78cb93a386Sopenharmony_ci if (![captureManager startCaptureWithDescriptor: captureDescriptor error:&error]) 79cb93a386Sopenharmony_ci { 80cb93a386Sopenharmony_ci NSLog(@"Failed to start capture, error %@", error); 81cb93a386Sopenharmony_ci } 82cb93a386Sopenharmony_ci } else { 83cb93a386Sopenharmony_ci [captureManager startCaptureWithCommandQueue: fQueue.get()]; 84cb93a386Sopenharmony_ci } 85cb93a386Sopenharmony_ci } 86cb93a386Sopenharmony_ci} 87cb93a386Sopenharmony_ci 88cb93a386Sopenharmony_civoid Gpu::testingOnly_endCapture() { 89cb93a386Sopenharmony_ci if (@available(macOS 10.13, iOS 11.0, *)) { 90cb93a386Sopenharmony_ci MTLCaptureManager* captureManager = [MTLCaptureManager sharedCaptureManager]; 91cb93a386Sopenharmony_ci if (captureManager.isCapturing) { 92cb93a386Sopenharmony_ci [captureManager stopCapture]; 93cb93a386Sopenharmony_ci } 94cb93a386Sopenharmony_ci } 95cb93a386Sopenharmony_ci} 96cb93a386Sopenharmony_ci#endif 97cb93a386Sopenharmony_ci 98cb93a386Sopenharmony_ci} // namespace skgpu::mtl 99