1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2017 Google Inc.
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#ifndef GrMtlGpu_DEFINED
9cb93a386Sopenharmony_ci#define GrMtlGpu_DEFINED
10cb93a386Sopenharmony_ci
11cb93a386Sopenharmony_ci#include "include/gpu/mtl/GrMtlBackendContext.h"
12cb93a386Sopenharmony_ci#include "include/private/GrMtlTypesPriv.h"
13cb93a386Sopenharmony_ci#include "include/private/SkDeque.h"
14cb93a386Sopenharmony_ci
15cb93a386Sopenharmony_ci#include "src/gpu/GrFinishCallbacks.h"
16cb93a386Sopenharmony_ci#include "src/gpu/GrGpu.h"
17cb93a386Sopenharmony_ci#include "src/gpu/GrRenderTarget.h"
18cb93a386Sopenharmony_ci#include "src/gpu/GrRingBuffer.h"
19cb93a386Sopenharmony_ci#include "src/gpu/GrSemaphore.h"
20cb93a386Sopenharmony_ci#include "src/gpu/GrStagingBufferManager.h"
21cb93a386Sopenharmony_ci#include "src/gpu/GrTexture.h"
22cb93a386Sopenharmony_ci
23cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlAttachment.h"
24cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlCaps.h"
25cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlCommandBuffer.h"
26cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlResourceProvider.h"
27cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlUtil.h"
28cb93a386Sopenharmony_ci
29cb93a386Sopenharmony_ci#import <Metal/Metal.h>
30cb93a386Sopenharmony_ci
31cb93a386Sopenharmony_ciclass GrMtlOpsRenderPass;
32cb93a386Sopenharmony_ciclass GrMtlTexture;
33cb93a386Sopenharmony_ciclass GrSemaphore;
34cb93a386Sopenharmony_ciclass GrMtlCommandBuffer;
35cb93a386Sopenharmony_ci
36cb93a386Sopenharmony_ciclass GrMtlGpu : public GrGpu {
37cb93a386Sopenharmony_cipublic:
38cb93a386Sopenharmony_ci    static sk_sp<GrGpu> Make(const GrMtlBackendContext&, const GrContextOptions&, GrDirectContext*);
39cb93a386Sopenharmony_ci    ~GrMtlGpu() override;
40cb93a386Sopenharmony_ci
41cb93a386Sopenharmony_ci    void disconnect(DisconnectType) override;
42cb93a386Sopenharmony_ci
43cb93a386Sopenharmony_ci    GrThreadSafePipelineBuilder* pipelineBuilder() override;
44cb93a386Sopenharmony_ci    sk_sp<GrThreadSafePipelineBuilder> refPipelineBuilder() override;
45cb93a386Sopenharmony_ci
46cb93a386Sopenharmony_ci    const GrMtlCaps& mtlCaps() const { return *fMtlCaps.get(); }
47cb93a386Sopenharmony_ci
48cb93a386Sopenharmony_ci    id<MTLDevice> device() const { return fDevice; }
49cb93a386Sopenharmony_ci
50cb93a386Sopenharmony_ci    GrMtlResourceProvider& resourceProvider() { return fResourceProvider; }
51cb93a386Sopenharmony_ci
52cb93a386Sopenharmony_ci    GrStagingBufferManager* stagingBufferManager() override { return &fStagingBufferManager; }
53cb93a386Sopenharmony_ci
54cb93a386Sopenharmony_ci    GrMtlCommandBuffer* commandBuffer();
55cb93a386Sopenharmony_ci
56cb93a386Sopenharmony_ci    enum SyncQueue {
57cb93a386Sopenharmony_ci        kForce_SyncQueue,
58cb93a386Sopenharmony_ci        kSkip_SyncQueue
59cb93a386Sopenharmony_ci    };
60cb93a386Sopenharmony_ci
61cb93a386Sopenharmony_ci    void deleteBackendTexture(const GrBackendTexture&) override;
62cb93a386Sopenharmony_ci
63cb93a386Sopenharmony_ci    bool compile(const GrProgramDesc&, const GrProgramInfo&) override;
64cb93a386Sopenharmony_ci
65cb93a386Sopenharmony_ci    bool precompileShader(const SkData& key, const SkData& data) override;
66cb93a386Sopenharmony_ci
67cb93a386Sopenharmony_ci#if GR_TEST_UTILS
68cb93a386Sopenharmony_ci    bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override;
69cb93a386Sopenharmony_ci
70cb93a386Sopenharmony_ci    GrBackendRenderTarget createTestingOnlyBackendRenderTarget(SkISize dimensions,
71cb93a386Sopenharmony_ci                                                               GrColorType,
72cb93a386Sopenharmony_ci                                                               int sampleCnt,
73cb93a386Sopenharmony_ci                                                               GrProtected) override;
74cb93a386Sopenharmony_ci    void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override;
75cb93a386Sopenharmony_ci
76cb93a386Sopenharmony_ci    void resetShaderCacheForTesting() const override {
77cb93a386Sopenharmony_ci        fResourceProvider.resetShaderCacheForTesting();
78cb93a386Sopenharmony_ci    }
79cb93a386Sopenharmony_ci#endif
80cb93a386Sopenharmony_ci
81cb93a386Sopenharmony_ci    void copySurfaceAsResolve(GrSurface* dst, GrSurface* src);
82cb93a386Sopenharmony_ci
83cb93a386Sopenharmony_ci    void copySurfaceAsBlit(GrSurface* dst, GrSurface* src,
84cb93a386Sopenharmony_ci                           GrMtlAttachment* dstAttachment, GrMtlAttachment* srcAttachment,
85cb93a386Sopenharmony_ci                           const SkIRect& srcRect, const SkIPoint& dstPoint);
86cb93a386Sopenharmony_ci
87cb93a386Sopenharmony_ci    bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
88cb93a386Sopenharmony_ci                       const SkIPoint& dstPoint) override;
89cb93a386Sopenharmony_ci
90cb93a386Sopenharmony_ci#if GR_METAL_SDK_VERSION >= 230
91cb93a386Sopenharmony_ci    id<MTLBinaryArchive> binaryArchive() const SK_API_AVAILABLE(macos(11.0), ios(14.0)) {
92cb93a386Sopenharmony_ci        return fBinaryArchive;
93cb93a386Sopenharmony_ci    }
94cb93a386Sopenharmony_ci#endif
95cb93a386Sopenharmony_ci
96cb93a386Sopenharmony_ci    void submit(GrOpsRenderPass* renderPass) override;
97cb93a386Sopenharmony_ci
98cb93a386Sopenharmony_ci    GrFence SK_WARN_UNUSED_RESULT insertFence() override;
99cb93a386Sopenharmony_ci    bool waitFence(GrFence) override;
100cb93a386Sopenharmony_ci    void deleteFence(GrFence) const override;
101cb93a386Sopenharmony_ci
102cb93a386Sopenharmony_ci    std::unique_ptr<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override;
103cb93a386Sopenharmony_ci    std::unique_ptr<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore&,
104cb93a386Sopenharmony_ci                                                      GrSemaphoreWrapType,
105cb93a386Sopenharmony_ci                                                      GrWrapOwnership) override;
106cb93a386Sopenharmony_ci    void insertSemaphore(GrSemaphore* semaphore) override;
107cb93a386Sopenharmony_ci    void waitSemaphore(GrSemaphore* semaphore) override;
108cb93a386Sopenharmony_ci    void checkFinishProcs() override { this->checkForFinishedCommandBuffers(); }
109cb93a386Sopenharmony_ci    void finishOutstandingGpuWork() override;
110cb93a386Sopenharmony_ci    std::unique_ptr<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override;
111cb93a386Sopenharmony_ci
112cb93a386Sopenharmony_ci    GrMtlRenderCommandEncoder* loadMSAAFromResolve(GrAttachment* dst,
113cb93a386Sopenharmony_ci                                                   GrMtlAttachment* src,
114cb93a386Sopenharmony_ci                                                   const SkIRect& srcRect,
115cb93a386Sopenharmony_ci                                                   MTLRenderPassStencilAttachmentDescriptor*);
116cb93a386Sopenharmony_ci
117cb93a386Sopenharmony_ci    // When the Metal backend actually uses indirect command buffers, this function will actually do
118cb93a386Sopenharmony_ci    // what it says. For now, every command is encoded directly into the primary command buffer, so
119cb93a386Sopenharmony_ci    // this function is pretty useless, except for indicating that a render target has been drawn
120cb93a386Sopenharmony_ci    // to.
121cb93a386Sopenharmony_ci    void submitIndirectCommandBuffer(GrSurface* surface, GrSurfaceOrigin origin,
122cb93a386Sopenharmony_ci                                     const SkIRect* bounds) {
123cb93a386Sopenharmony_ci        this->didWriteToSurface(surface, origin, bounds);
124cb93a386Sopenharmony_ci    }
125cb93a386Sopenharmony_ci
126cb93a386Sopenharmony_ci    GrRingBuffer* uniformsRingBuffer() override { return &fUniformsRingBuffer; }
127cb93a386Sopenharmony_ci
128cb93a386Sopenharmony_ciprivate:
129cb93a386Sopenharmony_ci    GrMtlGpu(GrDirectContext*, const GrContextOptions&, id<MTLDevice>,
130cb93a386Sopenharmony_ci             id<MTLCommandQueue>, GrMTLHandle binaryArchive);
131cb93a386Sopenharmony_ci
132cb93a386Sopenharmony_ci    void destroyResources();
133cb93a386Sopenharmony_ci
134cb93a386Sopenharmony_ci    void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
135cb93a386Sopenharmony_ci
136cb93a386Sopenharmony_ci    void takeOwnershipOfBuffer(sk_sp<GrGpuBuffer>) override;
137cb93a386Sopenharmony_ci
138cb93a386Sopenharmony_ci    GrBackendTexture onCreateBackendTexture(SkISize dimensions,
139cb93a386Sopenharmony_ci                                            const GrBackendFormat&,
140cb93a386Sopenharmony_ci                                            GrRenderable,
141cb93a386Sopenharmony_ci                                            GrMipmapped,
142cb93a386Sopenharmony_ci                                            GrProtected) override;
143cb93a386Sopenharmony_ci
144cb93a386Sopenharmony_ci    bool onClearBackendTexture(const GrBackendTexture&,
145cb93a386Sopenharmony_ci                               sk_sp<GrRefCntedCallback> finishedCallback,
146cb93a386Sopenharmony_ci                               std::array<float, 4> color) override;
147cb93a386Sopenharmony_ci
148cb93a386Sopenharmony_ci    GrBackendTexture onCreateCompressedBackendTexture(SkISize dimensions,
149cb93a386Sopenharmony_ci                                                      const GrBackendFormat&,
150cb93a386Sopenharmony_ci                                                      GrMipmapped,
151cb93a386Sopenharmony_ci                                                      GrProtected) override;
152cb93a386Sopenharmony_ci
153cb93a386Sopenharmony_ci    bool onUpdateCompressedBackendTexture(const GrBackendTexture&,
154cb93a386Sopenharmony_ci                                          sk_sp<GrRefCntedCallback> finishedCallback,
155cb93a386Sopenharmony_ci                                          const void* data,
156cb93a386Sopenharmony_ci                                          size_t size) override;
157cb93a386Sopenharmony_ci
158cb93a386Sopenharmony_ci    sk_sp<GrTexture> onCreateTexture(SkISize,
159cb93a386Sopenharmony_ci                                     const GrBackendFormat&,
160cb93a386Sopenharmony_ci                                     GrRenderable,
161cb93a386Sopenharmony_ci                                     int renderTargetSampleCnt,
162cb93a386Sopenharmony_ci                                     SkBudgeted,
163cb93a386Sopenharmony_ci                                     GrProtected,
164cb93a386Sopenharmony_ci                                     int mipLevelCount,
165cb93a386Sopenharmony_ci                                     uint32_t levelClearMask) override;
166cb93a386Sopenharmony_ci    sk_sp<GrTexture> onCreateCompressedTexture(SkISize dimensions,
167cb93a386Sopenharmony_ci                                               const GrBackendFormat&,
168cb93a386Sopenharmony_ci                                               SkBudgeted,
169cb93a386Sopenharmony_ci                                               GrMipmapped,
170cb93a386Sopenharmony_ci                                               GrProtected,
171cb93a386Sopenharmony_ci                                               const void* data, size_t dataSize) override;
172cb93a386Sopenharmony_ci
173cb93a386Sopenharmony_ci    sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&,
174cb93a386Sopenharmony_ci                                          GrWrapOwnership,
175cb93a386Sopenharmony_ci                                          GrWrapCacheable,
176cb93a386Sopenharmony_ci                                          GrIOType) override;
177cb93a386Sopenharmony_ci
178cb93a386Sopenharmony_ci    sk_sp<GrTexture> onWrapCompressedBackendTexture(const GrBackendTexture&,
179cb93a386Sopenharmony_ci                                                    GrWrapOwnership,
180cb93a386Sopenharmony_ci                                                    GrWrapCacheable) override;
181cb93a386Sopenharmony_ci
182cb93a386Sopenharmony_ci    sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
183cb93a386Sopenharmony_ci                                                    int sampleCnt,
184cb93a386Sopenharmony_ci                                                    GrWrapOwnership,
185cb93a386Sopenharmony_ci                                                    GrWrapCacheable) override;
186cb93a386Sopenharmony_ci
187cb93a386Sopenharmony_ci    sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override;
188cb93a386Sopenharmony_ci
189cb93a386Sopenharmony_ci    sk_sp<GrGpuBuffer> onCreateBuffer(size_t, GrGpuBufferType, GrAccessPattern,
190cb93a386Sopenharmony_ci                                      const void*) override;
191cb93a386Sopenharmony_ci
192cb93a386Sopenharmony_ci    bool onReadPixels(GrSurface* surface,
193cb93a386Sopenharmony_ci                      SkIRect,
194cb93a386Sopenharmony_ci                      GrColorType surfaceColorType,
195cb93a386Sopenharmony_ci                      GrColorType bufferColorType,
196cb93a386Sopenharmony_ci                      void*,
197cb93a386Sopenharmony_ci                      size_t rowBytes) override;
198cb93a386Sopenharmony_ci
199cb93a386Sopenharmony_ci    bool onWritePixels(GrSurface*,
200cb93a386Sopenharmony_ci                       SkIRect,
201cb93a386Sopenharmony_ci                       GrColorType surfaceColorType,
202cb93a386Sopenharmony_ci                       GrColorType bufferColorType,
203cb93a386Sopenharmony_ci                       const GrMipLevel[],
204cb93a386Sopenharmony_ci                       int mipLevelCount,
205cb93a386Sopenharmony_ci                       bool prepForTexSampling) override;
206cb93a386Sopenharmony_ci
207cb93a386Sopenharmony_ci    bool onTransferPixelsTo(GrTexture*,
208cb93a386Sopenharmony_ci                            SkIRect,
209cb93a386Sopenharmony_ci                            GrColorType textureColorType,
210cb93a386Sopenharmony_ci                            GrColorType bufferColorType,
211cb93a386Sopenharmony_ci                            sk_sp<GrGpuBuffer>,
212cb93a386Sopenharmony_ci                            size_t offset,
213cb93a386Sopenharmony_ci                            size_t rowBytes) override;
214cb93a386Sopenharmony_ci
215cb93a386Sopenharmony_ci    bool onTransferPixelsFrom(GrSurface*,
216cb93a386Sopenharmony_ci                              SkIRect,
217cb93a386Sopenharmony_ci                              GrColorType surfaceColorType,
218cb93a386Sopenharmony_ci                              GrColorType bufferColorType,
219cb93a386Sopenharmony_ci                              sk_sp<GrGpuBuffer>,
220cb93a386Sopenharmony_ci                              size_t offset) override;
221cb93a386Sopenharmony_ci
222cb93a386Sopenharmony_ci    bool onRegenerateMipMapLevels(GrTexture*) override;
223cb93a386Sopenharmony_ci
224cb93a386Sopenharmony_ci    void onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resolveRect) override;
225cb93a386Sopenharmony_ci
226cb93a386Sopenharmony_ci    void resolve(GrMtlAttachment* resolveAttachment, GrMtlAttachment* msaaAttachment);
227cb93a386Sopenharmony_ci
228cb93a386Sopenharmony_ci    void addFinishedProc(GrGpuFinishedProc finishedProc,
229cb93a386Sopenharmony_ci                         GrGpuFinishedContext finishedContext) override;
230cb93a386Sopenharmony_ci    void addFinishedCallback(sk_sp<GrRefCntedCallback> finishedCallback);
231cb93a386Sopenharmony_ci
232cb93a386Sopenharmony_ci    GrOpsRenderPass* onGetOpsRenderPass(GrRenderTarget*,
233cb93a386Sopenharmony_ci                                        bool useMSAASurface,
234cb93a386Sopenharmony_ci                                        GrAttachment*,
235cb93a386Sopenharmony_ci                                        GrSurfaceOrigin,
236cb93a386Sopenharmony_ci                                        const SkIRect&,
237cb93a386Sopenharmony_ci                                        const GrOpsRenderPass::LoadAndStoreInfo&,
238cb93a386Sopenharmony_ci                                        const GrOpsRenderPass::StencilLoadAndStoreInfo&,
239cb93a386Sopenharmony_ci                                        const SkTArray<GrSurfaceProxy*, true>& sampledProxies,
240cb93a386Sopenharmony_ci                                        GrXferBarrierFlags renderPassXferBarriers) override;
241cb93a386Sopenharmony_ci
242cb93a386Sopenharmony_ci    bool onSubmitToGpu(bool syncCpu) override;
243cb93a386Sopenharmony_ci
244cb93a386Sopenharmony_ci    // Commits the current command buffer to the queue and then creates a new command buffer. If
245cb93a386Sopenharmony_ci    // sync is set to kForce_SyncQueue, the function will wait for all work in the committed
246cb93a386Sopenharmony_ci    // command buffer to finish before returning.
247cb93a386Sopenharmony_ci    bool submitCommandBuffer(SyncQueue sync);
248cb93a386Sopenharmony_ci
249cb93a386Sopenharmony_ci    void checkForFinishedCommandBuffers();
250cb93a386Sopenharmony_ci
251cb93a386Sopenharmony_ci    // Function that uploads data onto textures with private storage mode (GPU access only).
252cb93a386Sopenharmony_ci    bool uploadToTexture(GrMtlTexture* tex,
253cb93a386Sopenharmony_ci                         SkIRect rect,
254cb93a386Sopenharmony_ci                         GrColorType dataColorType,
255cb93a386Sopenharmony_ci                         const GrMipLevel texels[],
256cb93a386Sopenharmony_ci                         int mipLevels);
257cb93a386Sopenharmony_ci
258cb93a386Sopenharmony_ci    // Function that fills texture levels with transparent black based on levelMask.
259cb93a386Sopenharmony_ci    bool clearTexture(GrMtlTexture*, size_t bbp, uint32_t levelMask);
260cb93a386Sopenharmony_ci
261cb93a386Sopenharmony_ci    bool readOrTransferPixels(GrSurface* surface,
262cb93a386Sopenharmony_ci                              SkIRect rect,
263cb93a386Sopenharmony_ci                              GrColorType dstColorType,
264cb93a386Sopenharmony_ci                              id<MTLBuffer> transferBuffer,
265cb93a386Sopenharmony_ci                              size_t offset,
266cb93a386Sopenharmony_ci                              size_t imageBytes,
267cb93a386Sopenharmony_ci                              size_t rowBytes);
268cb93a386Sopenharmony_ci
269cb93a386Sopenharmony_ci    sk_sp<GrAttachment> makeStencilAttachment(const GrBackendFormat& /*colorFormat*/,
270cb93a386Sopenharmony_ci                                              SkISize dimensions, int numStencilSamples) override;
271cb93a386Sopenharmony_ci
272cb93a386Sopenharmony_ci    GrBackendFormat getPreferredStencilFormat(const GrBackendFormat&) override {
273cb93a386Sopenharmony_ci        return GrBackendFormat::MakeMtl(this->mtlCaps().preferredStencilFormat());
274cb93a386Sopenharmony_ci    }
275cb93a386Sopenharmony_ci
276cb93a386Sopenharmony_ci    sk_sp<GrAttachment> makeMSAAAttachment(SkISize dimensions,
277cb93a386Sopenharmony_ci                                           const GrBackendFormat& format,
278cb93a386Sopenharmony_ci                                           int numSamples,
279cb93a386Sopenharmony_ci                                           GrProtected isProtected,
280cb93a386Sopenharmony_ci                                           GrMemoryless isMemoryless) override;
281cb93a386Sopenharmony_ci
282cb93a386Sopenharmony_ci    bool createMtlTextureForBackendSurface(MTLPixelFormat,
283cb93a386Sopenharmony_ci                                           SkISize dimensions,
284cb93a386Sopenharmony_ci                                           int sampleCnt,
285cb93a386Sopenharmony_ci                                           GrTexturable,
286cb93a386Sopenharmony_ci                                           GrRenderable,
287cb93a386Sopenharmony_ci                                           GrMipmapped,
288cb93a386Sopenharmony_ci                                           GrMtlTextureInfo*);
289cb93a386Sopenharmony_ci
290cb93a386Sopenharmony_ci#if GR_TEST_UTILS
291cb93a386Sopenharmony_ci    void testingOnly_startCapture() override;
292cb93a386Sopenharmony_ci    void testingOnly_endCapture() override;
293cb93a386Sopenharmony_ci#endif
294cb93a386Sopenharmony_ci
295cb93a386Sopenharmony_ci#ifdef SK_ENABLE_DUMP_GPU
296cb93a386Sopenharmony_ci    void onDumpJSON(SkJSONWriter*) const override;
297cb93a386Sopenharmony_ci#endif
298cb93a386Sopenharmony_ci
299cb93a386Sopenharmony_ci    sk_sp<GrMtlCaps> fMtlCaps;
300cb93a386Sopenharmony_ci
301cb93a386Sopenharmony_ci    id<MTLDevice> fDevice;
302cb93a386Sopenharmony_ci    id<MTLCommandQueue> fQueue;
303cb93a386Sopenharmony_ci
304cb93a386Sopenharmony_ci    sk_sp<GrMtlCommandBuffer> fCurrentCmdBuffer;
305cb93a386Sopenharmony_ci
306cb93a386Sopenharmony_ci    using OutstandingCommandBuffer = sk_sp<GrMtlCommandBuffer>;
307cb93a386Sopenharmony_ci    SkDeque fOutstandingCommandBuffers;
308cb93a386Sopenharmony_ci
309cb93a386Sopenharmony_ci#if GR_METAL_SDK_VERSION >= 230
310cb93a386Sopenharmony_ci    id<MTLBinaryArchive> fBinaryArchive SK_API_AVAILABLE(macos(11.0), ios(14.0));
311cb93a386Sopenharmony_ci#endif
312cb93a386Sopenharmony_ci
313cb93a386Sopenharmony_ci    GrMtlResourceProvider fResourceProvider;
314cb93a386Sopenharmony_ci    GrStagingBufferManager fStagingBufferManager;
315cb93a386Sopenharmony_ci    GrRingBuffer fUniformsRingBuffer;
316cb93a386Sopenharmony_ci
317cb93a386Sopenharmony_ci    bool fDisconnected;
318cb93a386Sopenharmony_ci
319cb93a386Sopenharmony_ci    using INHERITED = GrGpu;
320cb93a386Sopenharmony_ci};
321cb93a386Sopenharmony_ci
322cb93a386Sopenharmony_ci#endif
323cb93a386Sopenharmony_ci
324