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