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 "src/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 sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy( 53 [layer, drawable, sampleCnt](GrResourceProvider* resourceProvider) { 54 CAMetalLayer* metalLayer = (__bridge CAMetalLayer*)layer; 55 id<CAMetalDrawable> currentDrawable = [metalLayer nextDrawable]; 56 57 SkISize dims = {(int)metalLayer.drawableSize.width, 58 (int)metalLayer.drawableSize.height}; 59 60 GrMtlGpu* mtlGpu = (GrMtlGpu*) resourceProvider->priv().gpu(); 61 sk_sp<GrRenderTarget> surface; 62 if (metalLayer.framebufferOnly) { 63 surface = GrMtlRenderTarget::MakeWrappedRenderTarget(mtlGpu, dims, sampleCnt, 64 currentDrawable.texture); 65 } else { 66 surface = GrMtlTextureRenderTarget::MakeWrappedTextureRenderTarget( 67 mtlGpu, dims, sampleCnt, currentDrawable.texture, GrWrapCacheable::kNo); 68 } 69 if (surface && sampleCnt > 1) { 70 surface->setRequiresManualMSAAResolve(); 71 } 72 73 *drawable = (__bridge_retained GrMTLHandle) currentDrawable; 74 return GrSurfaceProxy::LazyCallbackResult(std::move(surface)); 75 }, 76 backendFormat, 77 dims, 78 sampleCnt, 79 sampleCnt > 1 ? GrInternalSurfaceFlags::kRequiresManualMSAAResolve 80 : GrInternalSurfaceFlags::kNone, 81 metalLayer.framebufferOnly ? nullptr : &texInfo, 82 GrMipMapsStatus::kNotAllocated, 83 SkBackingFit::kExact, 84 SkBudgeted::kYes, 85 GrProtected::kNo, 86 false, 87 GrSurfaceProxy::UseAllocator::kYes); 88 89 GrSwizzle readSwizzle = caps->getReadSwizzle(backendFormat, grColorType); 90 GrSwizzle writeSwizzle = caps->getWriteSwizzle(backendFormat, grColorType); 91 92 GrSurfaceProxyView readView(proxy, origin, readSwizzle); 93 GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle); 94 95 auto rtc = std::make_unique<GrRenderTargetContext>(context, std::move(readView), 96 std::move(writeView), grColorType, 97 colorSpace, surfaceProps); 98 99 sk_sp<SkSurface> surface = SkSurface_Gpu::MakeWrappedRenderTarget(context, std::move(rtc)); 100 return surface; 101} 102 103sk_sp<SkSurface> SkSurface::MakeFromMTKView(GrContext* context, 104 GrMTLHandle view, 105 GrSurfaceOrigin origin, 106 int sampleCnt, 107 SkColorType colorType, 108 sk_sp<SkColorSpace> colorSpace, 109 const SkSurfaceProps* surfaceProps) { 110 GrProxyProvider* proxyProvider = context->priv().proxyProvider(); 111 const GrCaps* caps = context->priv().caps(); 112 113 MTKView* mtkView = (__bridge MTKView*)view; 114 GrBackendFormat backendFormat = GrBackendFormat::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 = GrMipMapped::kNo; 122 texInfo.fTextureType = GrTextureType::k2D; 123 124 sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy( 125 [view, sampleCnt](GrResourceProvider* resourceProvider) { 126 MTKView* mtkView = (__bridge MTKView*)view; 127 id<CAMetalDrawable> currentDrawable = [mtkView currentDrawable]; 128 129 SkISize dims = {(int)mtkView.drawableSize.width, (int)mtkView.drawableSize.height}; 130 131 GrMtlGpu* mtlGpu = (GrMtlGpu*) resourceProvider->priv().gpu(); 132 sk_sp<GrRenderTarget> surface; 133 if (mtkView.framebufferOnly) { 134 surface = GrMtlRenderTarget::MakeWrappedRenderTarget(mtlGpu, dims, sampleCnt, 135 currentDrawable.texture); 136 } else { 137 surface = GrMtlTextureRenderTarget::MakeWrappedTextureRenderTarget( 138 mtlGpu, dims, sampleCnt, currentDrawable.texture, GrWrapCacheable::kNo); 139 } 140 if (surface && sampleCnt > 1) { 141 surface->setRequiresManualMSAAResolve(); 142 } 143 144 return GrSurfaceProxy::LazyCallbackResult(std::move(surface)); 145 }, 146 backendFormat, 147 dims, 148 sampleCnt, 149 sampleCnt > 1 ? GrInternalSurfaceFlags::kRequiresManualMSAAResolve 150 : GrInternalSurfaceFlags::kNone, 151 mtkView.framebufferOnly ? nullptr : &texInfo, 152 GrMipMapsStatus::kNotAllocated, 153 SkBackingFit::kExact, 154 SkBudgeted::kYes, 155 GrProtected::kNo, 156 false, 157 GrSurfaceProxy::UseAllocator::kYes); 158 159 GrSwizzle readSwizzle = caps->getReadSwizzle(backendFormat, grColorType); 160 GrSwizzle writeSwizzle = caps->getWriteSwizzle(backendFormat, grColorType); 161 162 GrSurfaceProxyView readView(proxy, origin, readSwizzle); 163 GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle); 164 165 auto rtc = std::make_unique<GrRenderTargetContext>(context, std::move(readView), 166 std::move(writeView), grColorType, 167 colorSpace, surfaceProps); 168 169 sk_sp<SkSurface> surface = SkSurface_Gpu::MakeWrappedRenderTarget(context, std::move(rtc)); 170 return surface; 171} 172 173#endif 174 175#endif 176