• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright 2021 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 "experimental/graphite/src/mtl/MtlGpu.h"
9
10#include "experimental/graphite/src/Caps.h"
11#include "experimental/graphite/src/mtl/MtlCommandBuffer.h"
12#include "experimental/graphite/src/mtl/MtlResourceProvider.h"
13
14namespace skgpu::mtl {
15
16sk_sp<skgpu::Gpu> Gpu::Make(const BackendContext& context) {
17    sk_cfp<id<MTLDevice>> device = sk_ret_cfp((id<MTLDevice>)(context.fDevice.get()));
18    sk_cfp<id<MTLCommandQueue>> queue = sk_ret_cfp((id<MTLCommandQueue>)(context.fQueue.get()));
19
20    sk_sp<const Caps> caps(new Caps(device.get()));
21
22    return sk_sp<skgpu::Gpu>(new Gpu(std::move(device), std::move(queue), std::move(caps)));
23}
24
25Gpu::Gpu(sk_cfp<id<MTLDevice>> device, sk_cfp<id<MTLCommandQueue>> queue, sk_sp<const Caps> caps)
26    : skgpu::Gpu(std::move(caps))
27    , fDevice(std::move(device))
28    , fQueue(std::move(queue)) {
29    fResourceProvider.reset(new ResourceProvider(this));
30}
31
32Gpu::~Gpu() {
33}
34
35class WorkSubmission final : public skgpu::GpuWorkSubmission {
36public:
37    WorkSubmission(sk_sp<CommandBuffer> cmdBuffer)
38        : fCommandBuffer(std::move(cmdBuffer)) {}
39    ~WorkSubmission() override {}
40
41    bool isFinished() override {
42        return fCommandBuffer->isFinished();
43    }
44    void waitUntilFinished(const skgpu::Gpu*) override {
45        return fCommandBuffer->waitUntilFinished();
46    }
47
48private:
49    sk_sp<CommandBuffer> fCommandBuffer;
50};
51
52bool Gpu::onSubmit(sk_sp<skgpu::CommandBuffer> commandBuffer) {
53    SkASSERT(commandBuffer);
54    sk_sp<CommandBuffer>& mtlCmdBuffer = (sk_sp<CommandBuffer>&)(commandBuffer);
55    if (!mtlCmdBuffer->commit()) {
56        return false;
57    }
58
59    std::unique_ptr<WorkSubmission> submission(new WorkSubmission(mtlCmdBuffer));
60    new (fOutstandingSubmissions.push_back()) OutstandingSubmission(std::move(submission));
61
62    return true;
63}
64
65#if GRAPHITE_TEST_UTILS
66void Gpu::testingOnly_startCapture() {
67    if (@available(macOS 10.13, iOS 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, *)) {
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 Gpu::testingOnly_endCapture() {
89    if (@available(macOS 10.13, iOS 11.0, *)) {
90        MTLCaptureManager* captureManager = [MTLCaptureManager sharedCaptureManager];
91        if (captureManager.isCapturing) {
92            [captureManager stopCapture];
93        }
94    }
95}
96#endif
97
98} // namespace skgpu::mtl
99