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/SkSurface.h"
9#include "include/gpu/GrBackendSurface.h"
10#include "include/gpu/GrContext.h"
11#include "include/gpu/mtl/GrMtlTypes.h"
12
13#if SK_SUPPORT_GPU
14
15#ifdef SK_METAL
16#import <Metal/Metal.h>
17#import <QuartzCore/CAMetalLayer.h>
18
19sk_sp<SkSurface> SkSurface::MakeFromCAMetalLayer(GrContext* context,
20                                                 GrMTLHandle layer,
21                                                 GrSurfaceOrigin origin,
22                                                 int sampleCnt,
23                                                 SkColorType colorType,
24                                                 sk_sp<SkColorSpace> colorSpace,
25                                                 const SkSurfaceProps* surfaceProps,
26                                                 GrMTLHandle* drawable) {
27    // TODO: Apple recommends grabbing the drawable (which we're implicitly doing here)
28    // for as little time as possible. I'm not sure it matters for our test apps, but
29    // you can get better throughput by doing any offscreen renders, texture uploads, or
30    // other non-dependant tasks first before grabbing the drawable.
31    CAMetalLayer* metalLayer = (__bridge CAMetalLayer*)layer;
32    id<CAMetalDrawable> currentDrawable = [metalLayer nextDrawable];
33
34    GrMtlTextureInfo fbInfo;
35    fbInfo.fTexture.retain((__bridge const void*)(currentDrawable.texture));
36
37    CGSize size = [metalLayer drawableSize];
38    sk_sp<SkSurface> surface;
39    if (sampleCnt <= 1) {
40        GrBackendRenderTarget backendRT(size.width,
41                                        size.height,
42                                        sampleCnt,
43                                        fbInfo);
44
45        surface = SkSurface::MakeFromBackendRenderTarget(context, backendRT, origin, colorType,
46                                                         colorSpace, surfaceProps);
47    } else {
48        GrBackendTexture backendTexture(size.width,
49                                        size.height,
50                                        GrMipMapped::kNo,
51                                        fbInfo);
52
53        surface = SkSurface::MakeFromBackendTexture(context, backendTexture, origin, sampleCnt,
54                                                    colorType, colorSpace, surfaceProps);
55    }
56    *drawable = (__bridge_retained GrMTLHandle) currentDrawable;
57
58    return surface;
59}
60#endif
61
62#endif
63