1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2018 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 "src/gpu/GrDirectContextPriv.h" 9cb93a386Sopenharmony_ci#include "src/gpu/GrResourceProvider.h" 10cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlGpu.h" 11cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlTextureRenderTarget.h" 12cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlUtil.h" 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_ci#if !__has_feature(objc_arc) 15cb93a386Sopenharmony_ci#error This file must be compiled with Arc. Use -fobjc-arc flag 16cb93a386Sopenharmony_ci#endif 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ciGR_NORETAIN_BEGIN 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_ciGrMtlTextureRenderTarget::GrMtlTextureRenderTarget(GrMtlGpu* gpu, 21cb93a386Sopenharmony_ci SkBudgeted budgeted, 22cb93a386Sopenharmony_ci SkISize dimensions, 23cb93a386Sopenharmony_ci sk_sp<GrMtlAttachment> texture, 24cb93a386Sopenharmony_ci sk_sp<GrMtlAttachment> colorAttachment, 25cb93a386Sopenharmony_ci sk_sp<GrMtlAttachment> resolveAttachment, 26cb93a386Sopenharmony_ci GrMipmapStatus mipmapStatus) 27cb93a386Sopenharmony_ci : GrSurface(gpu, dimensions, GrProtected::kNo) 28cb93a386Sopenharmony_ci , GrMtlTexture(gpu, dimensions, std::move(texture), mipmapStatus) 29cb93a386Sopenharmony_ci , GrMtlRenderTarget(gpu, dimensions, std::move(colorAttachment), 30cb93a386Sopenharmony_ci std::move(resolveAttachment)) { 31cb93a386Sopenharmony_ci this->registerWithCache(budgeted); 32cb93a386Sopenharmony_ci} 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ciGrMtlTextureRenderTarget::GrMtlTextureRenderTarget(GrMtlGpu* gpu, 35cb93a386Sopenharmony_ci SkISize dimensions, 36cb93a386Sopenharmony_ci sk_sp<GrMtlAttachment> texture, 37cb93a386Sopenharmony_ci sk_sp<GrMtlAttachment> colorAttachment, 38cb93a386Sopenharmony_ci sk_sp<GrMtlAttachment> resolveAttachment, 39cb93a386Sopenharmony_ci GrMipmapStatus mipmapStatus, 40cb93a386Sopenharmony_ci GrWrapCacheable cacheable) 41cb93a386Sopenharmony_ci : GrSurface(gpu, dimensions, GrProtected::kNo) 42cb93a386Sopenharmony_ci , GrMtlTexture(gpu, dimensions, std::move(texture), mipmapStatus) 43cb93a386Sopenharmony_ci , GrMtlRenderTarget(gpu, dimensions, std::move(colorAttachment), 44cb93a386Sopenharmony_ci std::move(resolveAttachment)) { 45cb93a386Sopenharmony_ci this->registerWithCacheWrapped(cacheable); 46cb93a386Sopenharmony_ci} 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_cibool create_rt_attachments(GrMtlGpu* gpu, SkISize dimensions, MTLPixelFormat format, int sampleCnt, 49cb93a386Sopenharmony_ci sk_sp<GrMtlAttachment> texture, sk_sp<GrMtlAttachment>* colorAttachment, 50cb93a386Sopenharmony_ci sk_sp<GrMtlAttachment>* resolveAttachment) { 51cb93a386Sopenharmony_ci if (sampleCnt > 1) { 52cb93a386Sopenharmony_ci auto rp = gpu->getContext()->priv().resourceProvider(); 53cb93a386Sopenharmony_ci sk_sp<GrAttachment> msaaAttachment = rp->makeMSAAAttachment( 54cb93a386Sopenharmony_ci dimensions, GrBackendFormat::MakeMtl(format), sampleCnt, GrProtected::kNo, 55cb93a386Sopenharmony_ci GrMemoryless::kNo); 56cb93a386Sopenharmony_ci if (!msaaAttachment) { 57cb93a386Sopenharmony_ci return false; 58cb93a386Sopenharmony_ci } 59cb93a386Sopenharmony_ci *colorAttachment = 60cb93a386Sopenharmony_ci sk_sp<GrMtlAttachment>(static_cast<GrMtlAttachment*>(msaaAttachment.release())); 61cb93a386Sopenharmony_ci *resolveAttachment = std::move(texture); 62cb93a386Sopenharmony_ci } else { 63cb93a386Sopenharmony_ci *colorAttachment = std::move(texture); 64cb93a386Sopenharmony_ci } 65cb93a386Sopenharmony_ci return true; 66cb93a386Sopenharmony_ci} 67cb93a386Sopenharmony_ci 68cb93a386Sopenharmony_cisk_sp<GrMtlTextureRenderTarget> GrMtlTextureRenderTarget::MakeNewTextureRenderTarget( 69cb93a386Sopenharmony_ci GrMtlGpu* gpu, 70cb93a386Sopenharmony_ci SkBudgeted budgeted, 71cb93a386Sopenharmony_ci SkISize dimensions, 72cb93a386Sopenharmony_ci int sampleCnt, 73cb93a386Sopenharmony_ci MTLPixelFormat format, 74cb93a386Sopenharmony_ci uint32_t mipLevels, 75cb93a386Sopenharmony_ci GrMipmapStatus mipmapStatus) { 76cb93a386Sopenharmony_ci sk_sp<GrMtlAttachment> textureAttachment = 77cb93a386Sopenharmony_ci GrMtlAttachment::MakeTexture(gpu, dimensions, format, mipLevels, GrRenderable::kYes, 78cb93a386Sopenharmony_ci /*numSamples=*/1, budgeted); 79cb93a386Sopenharmony_ci if (!textureAttachment) { 80cb93a386Sopenharmony_ci return nullptr; 81cb93a386Sopenharmony_ci } 82cb93a386Sopenharmony_ci if (@available(macOS 10.11, iOS 9.0, *)) { 83cb93a386Sopenharmony_ci SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & 84cb93a386Sopenharmony_ci textureAttachment->mtlTexture().usage); 85cb93a386Sopenharmony_ci } 86cb93a386Sopenharmony_ci 87cb93a386Sopenharmony_ci sk_sp<GrMtlAttachment> colorAttachment; 88cb93a386Sopenharmony_ci sk_sp<GrMtlAttachment> resolveAttachment; 89cb93a386Sopenharmony_ci if (!create_rt_attachments(gpu, dimensions, format, sampleCnt, textureAttachment, 90cb93a386Sopenharmony_ci &colorAttachment, &resolveAttachment)) { 91cb93a386Sopenharmony_ci return nullptr; 92cb93a386Sopenharmony_ci } 93cb93a386Sopenharmony_ci SkASSERT(colorAttachment); 94cb93a386Sopenharmony_ci SkASSERT(sampleCnt == 1 || resolveAttachment); 95cb93a386Sopenharmony_ci 96cb93a386Sopenharmony_ci return sk_sp<GrMtlTextureRenderTarget>(new GrMtlTextureRenderTarget( 97cb93a386Sopenharmony_ci gpu, budgeted, dimensions, std::move(textureAttachment), std::move(colorAttachment), 98cb93a386Sopenharmony_ci std::move(resolveAttachment), mipmapStatus)); 99cb93a386Sopenharmony_ci} 100cb93a386Sopenharmony_ci 101cb93a386Sopenharmony_cisk_sp<GrMtlTextureRenderTarget> GrMtlTextureRenderTarget::MakeWrappedTextureRenderTarget( 102cb93a386Sopenharmony_ci GrMtlGpu* gpu, 103cb93a386Sopenharmony_ci SkISize dimensions, 104cb93a386Sopenharmony_ci int sampleCnt, 105cb93a386Sopenharmony_ci id<MTLTexture> texture, 106cb93a386Sopenharmony_ci GrWrapCacheable cacheable) { 107cb93a386Sopenharmony_ci SkASSERT(nil != texture); 108cb93a386Sopenharmony_ci if (@available(macOS 10.11, iOS 9.0, *)) { 109cb93a386Sopenharmony_ci SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & texture.usage); 110cb93a386Sopenharmony_ci } 111cb93a386Sopenharmony_ci GrMipmapStatus mipmapStatus = texture.mipmapLevelCount > 1 112cb93a386Sopenharmony_ci ? GrMipmapStatus::kDirty 113cb93a386Sopenharmony_ci : GrMipmapStatus::kNotAllocated; 114cb93a386Sopenharmony_ci GrAttachment::UsageFlags textureUsageFlags = GrAttachment::UsageFlags::kTexture | 115cb93a386Sopenharmony_ci GrAttachment::UsageFlags::kColorAttachment; 116cb93a386Sopenharmony_ci sk_sp<GrMtlAttachment> textureAttachment = 117cb93a386Sopenharmony_ci GrMtlAttachment::MakeWrapped(gpu, dimensions, texture, textureUsageFlags, cacheable); 118cb93a386Sopenharmony_ci if (!textureAttachment) { 119cb93a386Sopenharmony_ci return nullptr; 120cb93a386Sopenharmony_ci } 121cb93a386Sopenharmony_ci 122cb93a386Sopenharmony_ci sk_sp<GrMtlAttachment> colorAttachment; 123cb93a386Sopenharmony_ci sk_sp<GrMtlAttachment> resolveAttachment; 124cb93a386Sopenharmony_ci if (!create_rt_attachments(gpu, dimensions, texture.pixelFormat, sampleCnt, textureAttachment, 125cb93a386Sopenharmony_ci &colorAttachment, &resolveAttachment)) { 126cb93a386Sopenharmony_ci return nullptr; 127cb93a386Sopenharmony_ci } 128cb93a386Sopenharmony_ci SkASSERT(colorAttachment); 129cb93a386Sopenharmony_ci SkASSERT(sampleCnt == 1 || resolveAttachment); 130cb93a386Sopenharmony_ci 131cb93a386Sopenharmony_ci return sk_sp<GrMtlTextureRenderTarget>(new GrMtlTextureRenderTarget( 132cb93a386Sopenharmony_ci gpu, dimensions, std::move(textureAttachment), std::move(colorAttachment), 133cb93a386Sopenharmony_ci std::move(resolveAttachment), mipmapStatus, cacheable)); 134cb93a386Sopenharmony_ci} 135cb93a386Sopenharmony_ci 136cb93a386Sopenharmony_cisize_t GrMtlTextureRenderTarget::onGpuMemorySize() const { 137cb93a386Sopenharmony_ci // The GrTexture[RenderTarget] is built up by a bunch of attachments each of which are their 138cb93a386Sopenharmony_ci // own GrGpuResource. Ideally the GrRenderTarget would not be a GrGpuResource and the GrTexture 139cb93a386Sopenharmony_ci // would just merge with the new GrSurface/Attachment world. Then we could just depend on each 140cb93a386Sopenharmony_ci // attachment to give its own size since we don't have GrGpuResources owning other 141cb93a386Sopenharmony_ci // GrGpuResources. Until we get to that point we need to live in some hybrid world. We will let 142cb93a386Sopenharmony_ci // the msaa and stencil attachments track their own size because they do get cached separately. 143cb93a386Sopenharmony_ci // For all GrTexture* based things we will continue to to use the GrTexture* to report size and 144cb93a386Sopenharmony_ci // the owned attachments will have no size and be uncached. 145cb93a386Sopenharmony_ci#ifdef SK_DEBUG 146cb93a386Sopenharmony_ci // The nonMSAA attachment (either color or resolve depending on numSamples should have size of 147cb93a386Sopenharmony_ci // zero since it is a texture attachment. 148cb93a386Sopenharmony_ci SkASSERT(this->nonMSAAAttachment()->gpuMemorySize() == 0); 149cb93a386Sopenharmony_ci if (this->numSamples() > 1) { 150cb93a386Sopenharmony_ci // Msaa attachment should have a valid size 151cb93a386Sopenharmony_ci SkASSERT(this->colorAttachment()->gpuMemorySize() == 152cb93a386Sopenharmony_ci GrSurface::ComputeSize(this->backendFormat(), this->dimensions(), 153cb93a386Sopenharmony_ci this->numSamples(), GrMipMapped::kNo)); 154cb93a386Sopenharmony_ci } 155cb93a386Sopenharmony_ci#endif 156cb93a386Sopenharmony_ci return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(), 157cb93a386Sopenharmony_ci 1 /*colorSamplesPerPixel*/, this->mipmapped()); 158cb93a386Sopenharmony_ci} 159cb93a386Sopenharmony_ci 160cb93a386Sopenharmony_ciGR_NORETAIN_END 161