• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright 2019 Google Inc.
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 "include/core/SkColorSpace.h"
9#include "include/core/SkRefCnt.h"
10#include "include/core/SkSurface.h"
11#include "include/gpu/ganesh/GrBackendSurface.h"
12#include "include/gpu/ganesh/mtl/GrMtlBackendSurface.h"
13#include "include/gpu/ganesh/mtl/GrMtlTypes.h"
14#include "include/gpu/ganesh/mtl/SkSurfaceMetal.h"
15#include "src/core/SkSurfacePriv.h"
16#include "src/gpu/ganesh/GrProxyProvider.h"
17#include "src/gpu/ganesh/GrRecordingContextPriv.h"
18#include "src/gpu/ganesh/GrResourceProvider.h"
19#include "src/gpu/ganesh/GrResourceProviderPriv.h"
20#include "src/gpu/ganesh/GrSurface.h"
21#include "src/gpu/ganesh/SurfaceDrawContext.h"
22#include "src/gpu/ganesh/mtl/GrMtlTextureRenderTarget.h"
23#include "src/gpu/ganesh/surface/SkSurface_Ganesh.h"
24
25#import <Metal/Metal.h>
26#import <MetalKit/MetalKit.h>
27#import <QuartzCore/CAMetalLayer.h>
28
29namespace SkSurfaces {
30
31sk_sp<SkSurface> WrapCAMetalLayer(GrRecordingContext* rContext,
32                                  GrMTLHandle layer,
33                                  GrSurfaceOrigin origin,
34                                  int sampleCnt,
35                                  SkColorType colorType,
36                                  sk_sp<SkColorSpace> colorSpace,
37                                  const SkSurfaceProps* surfaceProps,
38                                  GrMTLHandle* drawable) {
39    GrProxyProvider* proxyProvider = rContext->priv().proxyProvider();
40
41    CAMetalLayer* metalLayer = (__bridge CAMetalLayer*)layer;
42    GrBackendFormat backendFormat = GrBackendFormats::MakeMtl(metalLayer.pixelFormat);
43
44    GrColorType grColorType = SkColorTypeToGrColorType(colorType);
45
46    SkISize dims = {(int)metalLayer.drawableSize.width, (int)metalLayer.drawableSize.height};
47
48    GrProxyProvider::TextureInfo texInfo;
49    texInfo.fMipmapped = skgpu::Mipmapped::kNo;
50    texInfo.fTextureType = GrTextureType::k2D;
51
52    sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy(
53            [layer, drawable](GrResourceProvider* resourceProvider,
54                              const GrSurfaceProxy::LazySurfaceDesc& desc) {
55                CAMetalLayer* metalLayer = (__bridge CAMetalLayer*)layer;
56                id<CAMetalDrawable> currentDrawable = [metalLayer nextDrawable];
57
58                GrMtlGpu* mtlGpu = (GrMtlGpu*)resourceProvider->priv().gpu();
59                sk_sp<GrRenderTarget> surface;
60                if (metalLayer.framebufferOnly) {
61                    surface = GrMtlRenderTarget::MakeWrappedRenderTarget(
62                            mtlGpu, desc.fDimensions, desc.fSampleCnt, currentDrawable.texture);
63                } else {
64                    surface = GrMtlTextureRenderTarget::MakeWrappedTextureRenderTarget(
65                            mtlGpu,
66                            desc.fDimensions,
67                            desc.fSampleCnt,
68                            currentDrawable.texture,
69                            GrWrapCacheable::kNo);
70                }
71                if (surface && desc.fSampleCnt > 1) {
72                    surface->setRequiresManualMSAAResolve();
73                }
74
75                *drawable = (__bridge_retained GrMTLHandle)currentDrawable;
76                return GrSurfaceProxy::LazyCallbackResult(std::move(surface));
77            },
78            backendFormat,
79            dims,
80            sampleCnt,
81            sampleCnt > 1 ? GrInternalSurfaceFlags::kRequiresManualMSAAResolve
82                          : GrInternalSurfaceFlags::kNone,
83            metalLayer.framebufferOnly ? nullptr : &texInfo,
84            GrMipmapStatus::kNotAllocated,
85            SkBackingFit::kExact,
86            skgpu::Budgeted::kYes,
87            GrProtected::kNo,
88            false,
89            GrSurfaceProxy::UseAllocator::kYes);
90
91    auto device = rContext->priv().createDevice(grColorType,
92                                                std::move(proxy),
93                                                std::move(colorSpace),
94                                                origin,
95                                                SkSurfacePropsCopyOrDefault(surfaceProps),
96                                                skgpu::ganesh::Device::InitContents::kUninit);
97    if (!device) {
98        return nullptr;
99    }
100
101    return sk_make_sp<SkSurface_Ganesh>(std::move(device));
102}
103
104sk_sp<SkSurface> WrapMTKView(GrRecordingContext* rContext,
105                             GrMTLHandle view,
106                             GrSurfaceOrigin origin,
107                             int sampleCnt,
108                             SkColorType colorType,
109                             sk_sp<SkColorSpace> colorSpace,
110                             const SkSurfaceProps* surfaceProps) {
111    GrProxyProvider* proxyProvider = rContext->priv().proxyProvider();
112
113    MTKView* mtkView = (__bridge MTKView*)view;
114    GrBackendFormat backendFormat = GrBackendFormats::MakeMtl(mtkView.colorPixelFormat);
115
116    GrColorType grColorType = SkColorTypeToGrColorType(colorType);
117
118    SkISize dims = {(int)mtkView.drawableSize.width, (int)mtkView.drawableSize.height};
119
120    GrProxyProvider::TextureInfo texInfo;
121    texInfo.fMipmapped = skgpu::Mipmapped::kNo;
122    texInfo.fTextureType = GrTextureType::k2D;
123
124    sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy(
125            [view](GrResourceProvider* resourceProvider,
126                   const GrSurfaceProxy::LazySurfaceDesc& desc) {
127                MTKView* mtkView = (__bridge MTKView*)view;
128                id<CAMetalDrawable> currentDrawable = [mtkView currentDrawable];
129
130                GrMtlGpu* mtlGpu = (GrMtlGpu*)resourceProvider->priv().gpu();
131                sk_sp<GrRenderTarget> surface;
132                if (mtkView.framebufferOnly) {
133                    surface = GrMtlRenderTarget::MakeWrappedRenderTarget(
134                            mtlGpu, desc.fDimensions, desc.fSampleCnt, currentDrawable.texture);
135                } else {
136                    surface = GrMtlTextureRenderTarget::MakeWrappedTextureRenderTarget(
137                            mtlGpu,
138                            desc.fDimensions,
139                            desc.fSampleCnt,
140                            currentDrawable.texture,
141                            GrWrapCacheable::kNo);
142                }
143                if (surface && desc.fSampleCnt > 1) {
144                    surface->setRequiresManualMSAAResolve();
145                }
146
147                return GrSurfaceProxy::LazyCallbackResult(std::move(surface));
148            },
149            backendFormat,
150            dims,
151            sampleCnt,
152            sampleCnt > 1 ? GrInternalSurfaceFlags::kRequiresManualMSAAResolve
153                          : GrInternalSurfaceFlags::kNone,
154            mtkView.framebufferOnly ? nullptr : &texInfo,
155            GrMipmapStatus::kNotAllocated,
156            SkBackingFit::kExact,
157            skgpu::Budgeted::kYes,
158            GrProtected::kNo,
159            false,
160            GrSurfaceProxy::UseAllocator::kYes);
161
162    auto device = rContext->priv().createDevice(grColorType,
163                                                std::move(proxy),
164                                                std::move(colorSpace),
165                                                origin,
166                                                SkSurfacePropsCopyOrDefault(surfaceProps),
167                                                skgpu::ganesh::Device::InitContents::kUninit);
168    if (!device) {
169        return nullptr;
170    }
171
172    return sk_make_sp<SkSurface_Ganesh>(std::move(device));
173}
174
175}  // namespace SkSurfaces
176