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