1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2019 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkRefCnt.h" 9cb93a386Sopenharmony_ci#include "include/core/SkSurface.h" 10cb93a386Sopenharmony_ci#include "include/gpu/GrBackendSurface.h" 11cb93a386Sopenharmony_ci#include "include/gpu/mtl/GrMtlTypes.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrProxyProvider.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrRecordingContextPriv.h" 14cb93a386Sopenharmony_ci#include "src/gpu/GrResourceProvider.h" 15cb93a386Sopenharmony_ci#include "src/gpu/GrResourceProviderPriv.h" 16cb93a386Sopenharmony_ci#include "src/gpu/v1/SurfaceDrawContext_v1.h" 17cb93a386Sopenharmony_ci#include "src/image/SkSurface_Gpu.h" 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci#if SK_SUPPORT_GPU 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_ci#include "src/gpu/GrSurface.h" 22cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlTextureRenderTarget.h" 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ci#ifdef SK_METAL 25cb93a386Sopenharmony_ci#import <Metal/Metal.h> 26cb93a386Sopenharmony_ci#import <QuartzCore/CAMetalLayer.h> 27cb93a386Sopenharmony_ci#import <MetalKit/MetalKit.h> 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_cisk_sp<SkSurface> SkSurface::MakeFromCAMetalLayer(GrRecordingContext* rContext, 30cb93a386Sopenharmony_ci GrMTLHandle layer, 31cb93a386Sopenharmony_ci GrSurfaceOrigin origin, 32cb93a386Sopenharmony_ci int sampleCnt, 33cb93a386Sopenharmony_ci SkColorType colorType, 34cb93a386Sopenharmony_ci sk_sp<SkColorSpace> colorSpace, 35cb93a386Sopenharmony_ci const SkSurfaceProps* surfaceProps, 36cb93a386Sopenharmony_ci GrMTLHandle* drawable) { 37cb93a386Sopenharmony_ci GrProxyProvider* proxyProvider = rContext->priv().proxyProvider(); 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_ci CAMetalLayer* metalLayer = (__bridge CAMetalLayer*)layer; 40cb93a386Sopenharmony_ci GrBackendFormat backendFormat = GrBackendFormat::MakeMtl(metalLayer.pixelFormat); 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ci GrColorType grColorType = SkColorTypeToGrColorType(colorType); 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_ci SkISize dims = {(int)metalLayer.drawableSize.width, (int)metalLayer.drawableSize.height}; 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_ci GrProxyProvider::TextureInfo texInfo; 47cb93a386Sopenharmony_ci texInfo.fMipmapped = GrMipmapped::kNo; 48cb93a386Sopenharmony_ci texInfo.fTextureType = GrTextureType::k2D; 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ci sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy( 51cb93a386Sopenharmony_ci [layer, drawable](GrResourceProvider* resourceProvider, 52cb93a386Sopenharmony_ci const GrSurfaceProxy::LazySurfaceDesc& desc) { 53cb93a386Sopenharmony_ci CAMetalLayer* metalLayer = (__bridge CAMetalLayer*)layer; 54cb93a386Sopenharmony_ci id<CAMetalDrawable> currentDrawable = [metalLayer nextDrawable]; 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ci GrMtlGpu* mtlGpu = (GrMtlGpu*) resourceProvider->priv().gpu(); 57cb93a386Sopenharmony_ci sk_sp<GrRenderTarget> surface; 58cb93a386Sopenharmony_ci if (metalLayer.framebufferOnly) { 59cb93a386Sopenharmony_ci surface = GrMtlRenderTarget::MakeWrappedRenderTarget( 60cb93a386Sopenharmony_ci mtlGpu, desc.fDimensions, desc.fSampleCnt, currentDrawable.texture); 61cb93a386Sopenharmony_ci } else { 62cb93a386Sopenharmony_ci surface = GrMtlTextureRenderTarget::MakeWrappedTextureRenderTarget( 63cb93a386Sopenharmony_ci mtlGpu, desc.fDimensions, desc.fSampleCnt, currentDrawable.texture, 64cb93a386Sopenharmony_ci GrWrapCacheable::kNo); 65cb93a386Sopenharmony_ci } 66cb93a386Sopenharmony_ci if (surface && desc.fSampleCnt > 1) { 67cb93a386Sopenharmony_ci surface->setRequiresManualMSAAResolve(); 68cb93a386Sopenharmony_ci } 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci *drawable = (__bridge_retained GrMTLHandle) currentDrawable; 71cb93a386Sopenharmony_ci return GrSurfaceProxy::LazyCallbackResult(std::move(surface)); 72cb93a386Sopenharmony_ci }, 73cb93a386Sopenharmony_ci backendFormat, 74cb93a386Sopenharmony_ci dims, 75cb93a386Sopenharmony_ci sampleCnt, 76cb93a386Sopenharmony_ci sampleCnt > 1 ? GrInternalSurfaceFlags::kRequiresManualMSAAResolve 77cb93a386Sopenharmony_ci : GrInternalSurfaceFlags::kNone, 78cb93a386Sopenharmony_ci metalLayer.framebufferOnly ? nullptr : &texInfo, 79cb93a386Sopenharmony_ci GrMipmapStatus::kNotAllocated, 80cb93a386Sopenharmony_ci SkBackingFit::kExact, 81cb93a386Sopenharmony_ci SkBudgeted::kYes, 82cb93a386Sopenharmony_ci GrProtected::kNo, 83cb93a386Sopenharmony_ci false, 84cb93a386Sopenharmony_ci GrSurfaceProxy::UseAllocator::kYes); 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ci auto device = rContext->priv().createDevice(grColorType, 87cb93a386Sopenharmony_ci std::move(proxy), 88cb93a386Sopenharmony_ci std::move(colorSpace), 89cb93a386Sopenharmony_ci origin, 90cb93a386Sopenharmony_ci SkSurfacePropsCopyOrDefault(surfaceProps), 91cb93a386Sopenharmony_ci skgpu::BaseDevice::InitContents::kUninit); 92cb93a386Sopenharmony_ci if (!device) { 93cb93a386Sopenharmony_ci return nullptr; 94cb93a386Sopenharmony_ci } 95cb93a386Sopenharmony_ci 96cb93a386Sopenharmony_ci return sk_make_sp<SkSurface_Gpu>(std::move(device)); 97cb93a386Sopenharmony_ci} 98cb93a386Sopenharmony_ci 99cb93a386Sopenharmony_cisk_sp<SkSurface> SkSurface::MakeFromMTKView(GrRecordingContext* rContext, 100cb93a386Sopenharmony_ci GrMTLHandle view, 101cb93a386Sopenharmony_ci GrSurfaceOrigin origin, 102cb93a386Sopenharmony_ci int sampleCnt, 103cb93a386Sopenharmony_ci SkColorType colorType, 104cb93a386Sopenharmony_ci sk_sp<SkColorSpace> colorSpace, 105cb93a386Sopenharmony_ci const SkSurfaceProps* surfaceProps) { 106cb93a386Sopenharmony_ci GrProxyProvider* proxyProvider = rContext->priv().proxyProvider(); 107cb93a386Sopenharmony_ci 108cb93a386Sopenharmony_ci MTKView* mtkView = (__bridge MTKView*)view; 109cb93a386Sopenharmony_ci GrBackendFormat backendFormat = GrBackendFormat::MakeMtl(mtkView.colorPixelFormat); 110cb93a386Sopenharmony_ci 111cb93a386Sopenharmony_ci GrColorType grColorType = SkColorTypeToGrColorType(colorType); 112cb93a386Sopenharmony_ci 113cb93a386Sopenharmony_ci SkISize dims = {(int)mtkView.drawableSize.width, (int)mtkView.drawableSize.height}; 114cb93a386Sopenharmony_ci 115cb93a386Sopenharmony_ci GrProxyProvider::TextureInfo texInfo; 116cb93a386Sopenharmony_ci texInfo.fMipmapped = GrMipmapped::kNo; 117cb93a386Sopenharmony_ci texInfo.fTextureType = GrTextureType::k2D; 118cb93a386Sopenharmony_ci 119cb93a386Sopenharmony_ci sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy( 120cb93a386Sopenharmony_ci [view](GrResourceProvider* resourceProvider, 121cb93a386Sopenharmony_ci const GrSurfaceProxy::LazySurfaceDesc& desc) { 122cb93a386Sopenharmony_ci MTKView* mtkView = (__bridge MTKView*)view; 123cb93a386Sopenharmony_ci id<CAMetalDrawable> currentDrawable = [mtkView currentDrawable]; 124cb93a386Sopenharmony_ci 125cb93a386Sopenharmony_ci GrMtlGpu* mtlGpu = (GrMtlGpu*) resourceProvider->priv().gpu(); 126cb93a386Sopenharmony_ci sk_sp<GrRenderTarget> surface; 127cb93a386Sopenharmony_ci if (mtkView.framebufferOnly) { 128cb93a386Sopenharmony_ci surface = GrMtlRenderTarget::MakeWrappedRenderTarget( 129cb93a386Sopenharmony_ci mtlGpu, desc.fDimensions, desc.fSampleCnt, currentDrawable.texture); 130cb93a386Sopenharmony_ci } else { 131cb93a386Sopenharmony_ci surface = GrMtlTextureRenderTarget::MakeWrappedTextureRenderTarget( 132cb93a386Sopenharmony_ci mtlGpu, desc.fDimensions, desc.fSampleCnt, currentDrawable.texture, 133cb93a386Sopenharmony_ci GrWrapCacheable::kNo); 134cb93a386Sopenharmony_ci } 135cb93a386Sopenharmony_ci if (surface && desc.fSampleCnt > 1) { 136cb93a386Sopenharmony_ci surface->setRequiresManualMSAAResolve(); 137cb93a386Sopenharmony_ci } 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_ci return GrSurfaceProxy::LazyCallbackResult(std::move(surface)); 140cb93a386Sopenharmony_ci }, 141cb93a386Sopenharmony_ci backendFormat, 142cb93a386Sopenharmony_ci dims, 143cb93a386Sopenharmony_ci sampleCnt, 144cb93a386Sopenharmony_ci sampleCnt > 1 ? GrInternalSurfaceFlags::kRequiresManualMSAAResolve 145cb93a386Sopenharmony_ci : GrInternalSurfaceFlags::kNone, 146cb93a386Sopenharmony_ci mtkView.framebufferOnly ? nullptr : &texInfo, 147cb93a386Sopenharmony_ci GrMipmapStatus::kNotAllocated, 148cb93a386Sopenharmony_ci SkBackingFit::kExact, 149cb93a386Sopenharmony_ci SkBudgeted::kYes, 150cb93a386Sopenharmony_ci GrProtected::kNo, 151cb93a386Sopenharmony_ci false, 152cb93a386Sopenharmony_ci GrSurfaceProxy::UseAllocator::kYes); 153cb93a386Sopenharmony_ci 154cb93a386Sopenharmony_ci 155cb93a386Sopenharmony_ci auto device = rContext->priv().createDevice(grColorType, 156cb93a386Sopenharmony_ci std::move(proxy), 157cb93a386Sopenharmony_ci std::move(colorSpace), 158cb93a386Sopenharmony_ci origin, 159cb93a386Sopenharmony_ci SkSurfacePropsCopyOrDefault(surfaceProps), 160cb93a386Sopenharmony_ci skgpu::BaseDevice::InitContents::kUninit); 161cb93a386Sopenharmony_ci if (!device) { 162cb93a386Sopenharmony_ci return nullptr; 163cb93a386Sopenharmony_ci } 164cb93a386Sopenharmony_ci 165cb93a386Sopenharmony_ci return sk_make_sp<SkSurface_Gpu>(std::move(device)); 166cb93a386Sopenharmony_ci} 167cb93a386Sopenharmony_ci 168cb93a386Sopenharmony_ci#endif 169cb93a386Sopenharmony_ci 170cb93a386Sopenharmony_ci#endif 171