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