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