1/* 2 * Copyright 2017 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 "src/gpu/mtl/GrMtlRenderTarget.h" 9 10#include "src/gpu/mtl/GrMtlGpu.h" 11#include "src/gpu/mtl/GrMtlUtil.h" 12 13#if !__has_feature(objc_arc) 14#error This file must be compiled with Arc. Use -fobjc-arc flag 15#endif 16 17// Called for wrapped non-texture render targets. 18GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu, 19 SkISize dimensions, 20 int sampleCnt, 21 id<MTLTexture> colorTexture, 22 id<MTLTexture> resolveTexture, 23 Wrapped) 24 : GrSurface(gpu, dimensions, GrProtected::kNo) 25 , GrRenderTarget(gpu, dimensions, sampleCnt, GrProtected::kNo) 26 , fColorTexture(colorTexture) 27 , fResolveTexture(resolveTexture) { 28 SkASSERT(sampleCnt > 1); 29 this->registerWithCacheWrapped(GrWrapCacheable::kNo); 30} 31 32GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu, 33 SkISize dimensions, 34 id<MTLTexture> colorTexture, 35 Wrapped) 36 : GrSurface(gpu, dimensions, GrProtected::kNo) 37 , GrRenderTarget(gpu, dimensions, 1, GrProtected::kNo) 38 , fColorTexture(colorTexture) 39 , fResolveTexture(nil) { 40 this->registerWithCacheWrapped(GrWrapCacheable::kNo); 41} 42 43// Called by subclass constructors. 44GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu, 45 SkISize dimensions, 46 int sampleCnt, 47 id<MTLTexture> colorTexture, 48 id<MTLTexture> resolveTexture) 49 : GrSurface(gpu, dimensions, GrProtected::kNo) 50 , GrRenderTarget(gpu, dimensions, sampleCnt, GrProtected::kNo) 51 , fColorTexture(colorTexture) 52 , fResolveTexture(resolveTexture) { 53 SkASSERT(sampleCnt > 1); 54} 55 56GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu, SkISize dimensions, id<MTLTexture> colorTexture) 57 : GrSurface(gpu, dimensions, GrProtected::kNo) 58 , GrRenderTarget(gpu, dimensions, 1, GrProtected::kNo) 59 , fColorTexture(colorTexture) 60 , fResolveTexture(nil) {} 61 62sk_sp<GrMtlRenderTarget> GrMtlRenderTarget::MakeWrappedRenderTarget(GrMtlGpu* gpu, 63 SkISize dimensions, 64 int sampleCnt, 65 id<MTLTexture> texture) { 66 SkASSERT(nil != texture); 67 SkASSERT(1 == texture.mipmapLevelCount); 68 if (@available(macOS 10.11, iOS 9.0, *)) { 69 SkASSERT(MTLTextureUsageRenderTarget & texture.usage); 70 } 71 72 GrMtlRenderTarget* mtlRT; 73 if (sampleCnt > 1) { 74 MTLPixelFormat format = texture.pixelFormat; 75 if (!gpu->mtlCaps().isFormatRenderable(format, sampleCnt)) { 76 return nullptr; 77 } 78 MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init]; 79 texDesc.textureType = MTLTextureType2DMultisample; 80 texDesc.pixelFormat = format; 81 texDesc.width = dimensions.fWidth; 82 texDesc.height = dimensions.fHeight; 83 texDesc.depth = 1; 84 texDesc.mipmapLevelCount = 1; 85 texDesc.sampleCount = sampleCnt; 86 texDesc.arrayLength = 1; 87 if (@available(macOS 10.11, iOS 9.0, *)) { 88 texDesc.storageMode = MTLStorageModePrivate; 89 texDesc.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget; 90 } 91 92 id<MTLTexture> colorTexture = [gpu->device() newTextureWithDescriptor:texDesc]; 93 if (!colorTexture) { 94 return nullptr; 95 } 96 if (@available(macOS 10.11, iOS 9.0, *)) { 97 SkASSERT((MTLTextureUsageShaderRead|MTLTextureUsageRenderTarget) & colorTexture.usage); 98 } 99 mtlRT = new GrMtlRenderTarget(gpu, dimensions, sampleCnt, colorTexture, texture, kWrapped); 100 } else { 101 mtlRT = new GrMtlRenderTarget(gpu, dimensions, texture, kWrapped); 102 } 103 104 return sk_sp<GrMtlRenderTarget>(mtlRT); 105} 106 107GrMtlRenderTarget::~GrMtlRenderTarget() { 108 SkASSERT(nil == fColorTexture); 109 SkASSERT(nil == fResolveTexture); 110} 111 112GrBackendRenderTarget GrMtlRenderTarget::getBackendRenderTarget() const { 113 GrMtlTextureInfo info; 114 info.fTexture.reset(GrRetainPtrFromId(fColorTexture)); 115 return GrBackendRenderTarget(this->width(), this->height(), fColorTexture.sampleCount, info); 116} 117 118GrBackendFormat GrMtlRenderTarget::backendFormat() const { 119 return GrBackendFormat::MakeMtl(fColorTexture.pixelFormat); 120} 121 122GrMtlGpu* GrMtlRenderTarget::getMtlGpu() const { 123 SkASSERT(!this->wasDestroyed()); 124 return static_cast<GrMtlGpu*>(this->getGpu()); 125} 126 127void GrMtlRenderTarget::onAbandon() { 128 fColorTexture = nil; 129 fResolveTexture = nil; 130 INHERITED::onAbandon(); 131} 132 133void GrMtlRenderTarget::onRelease() { 134 fColorTexture = nil; 135 fResolveTexture = nil; 136 INHERITED::onRelease(); 137} 138 139bool GrMtlRenderTarget::completeStencilAttachment() { 140 return true; 141} 142 143