/* * Copyright 2017 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "GrMtlTexture.h" #include "GrMtlGpu.h" #include "GrMtlUtil.h" #include "GrTexturePriv.h" sk_sp GrMtlTexture::CreateNewTexture(GrMtlGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc, int mipLevels) { MTLPixelFormat format; if (!GrPixelConfigToMTLFormat(desc.fConfig, &format)) { return nullptr; } MTLTextureDescriptor* descriptor = [[MTLTextureDescriptor alloc] init]; descriptor.textureType = MTLTextureType2D; descriptor.pixelFormat = format; descriptor.width = desc.fWidth; descriptor.height = desc.fHeight; descriptor.depth = 1; descriptor.mipmapLevelCount = mipLevels; descriptor.sampleCount = 1; descriptor.arrayLength = 1; // descriptor.resourceOptions This looks to be set by setting cpuCacheMode and storageModes descriptor.cpuCacheMode = MTLCPUCacheModeWriteCombined; // Shared is not available on MacOS. Is there a reason to want managed to allow mapping? descriptor.storageMode = MTLStorageModePrivate; MTLTextureUsage texUsage = MTLTextureUsageShaderRead; if (GrMTLFormatIsSRGB(format, nullptr)) { texUsage |= MTLTextureUsagePixelFormatView; } descriptor.usage = texUsage; id texture = [gpu->device() newTextureWithDescriptor:descriptor]; GrMipMapsStatus mipMapsStatus = mipLevels > 1 ? GrMipMapsStatus::kValid : GrMipMapsStatus::kNotAllocated; return sk_sp(new GrMtlTexture(gpu, budgeted, desc, texture, mipMapsStatus)); } // This method parallels GrTextureProxy::highestFilterMode static inline GrSamplerState::Filter highest_filter_mode(GrPixelConfig config) { if (GrPixelConfigIsSint(config)) { // We only ever want to nearest-neighbor sample signed int textures. return GrSamplerState::Filter::kNearest; } return GrSamplerState::Filter::kMipMap; } GrMtlTexture::GrMtlTexture(GrMtlGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc, id texture, GrMipMapsStatus mipMapsStatus) : GrSurface(gpu, desc) , INHERITED(gpu, desc, kTexture2DSampler_GrSLType, highest_filter_mode(desc.fConfig), mipMapsStatus) , fTexture(texture) { } GrMtlTexture::~GrMtlTexture() { SkASSERT(nil == fTexture); } GrMtlGpu* GrMtlTexture::getMtlGpu() const { SkASSERT(!this->wasDestroyed()); return static_cast(this->getGpu()); } GrBackendObject GrMtlTexture::getTextureHandle() const { void* voidTex = (__bridge_retained void*)fTexture; return (GrBackendObject)voidTex; } GrBackendTexture GrMtlTexture::getBackendTexture() const { return GrBackendTexture(); // invalid }