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