xref: /aosp_15_r20/external/skia/src/gpu/graphite/mtl/MtlQueueManager.mm (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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