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