1/* 2 * Copyright 2024 Google LLC 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#include "include/core/SkStream.h" 8#include "include/core/SkString.h" 9#include "include/gpu/graphite/mtl/MtlGraphiteTypes.h" 10#include "src/gpu/graphite/TextureInfoPriv.h" 11#include "src/gpu/graphite/mtl/MtlGraphiteUtils.h" 12#include "src/gpu/mtl/MtlUtilsPriv.h" 13 14#include <cstdint> 15 16#import <Metal/Metal.h> 17 18class SkStream; 19 20namespace skgpu::graphite { 21 22MtlTextureInfo::MtlTextureInfo(CFTypeRef texture) { 23 SkASSERT(texture); 24 id<MTLTexture> mtlTex = (id<MTLTexture>)texture; 25 26 fSampleCount = mtlTex.sampleCount; 27 fMipmapped = mtlTex.mipmapLevelCount > 1 ? Mipmapped::kYes : Mipmapped::kNo; 28 29 fFormat = mtlTex.pixelFormat; 30 fUsage = mtlTex.usage; 31 fStorageMode = mtlTex.storageMode; 32 fFramebufferOnly = mtlTex.framebufferOnly; 33} 34 35TextureFormat MtlTextureInfo::viewFormat() const { 36 return MTLPixelFormatToTextureFormat(fFormat); 37} 38 39SkString MtlTextureInfo::toBackendString() const { 40 return SkStringPrintf("usage=0x%04X,storageMode=%u,framebufferOnly=%d", 41 (uint32_t)fUsage, 42 (uint32_t)fStorageMode, 43 fFramebufferOnly); 44} 45 46bool MtlTextureInfo::isCompatible(const TextureInfo& that, bool requireExact) const { 47 const auto& mt = TextureInfoPriv::Get<MtlTextureInfo>(that); 48 // The usages may match or the usage passed in may be a superset of the usage stored within. 49 const auto usageMask = requireExact ? mt.fUsage : fUsage; 50 return fFormat == mt.fFormat && 51 fStorageMode == mt.fStorageMode && 52 fFramebufferOnly == mt.fFramebufferOnly && 53 (usageMask & mt.fUsage) == fUsage; 54} 55 56bool MtlTextureInfo::serialize(SkWStream* stream) const { 57 SkASSERT(fFormat < (1u << 24)); 58 SkASSERT(fUsage < (1u << 5)); 59 SkASSERT(fStorageMode < (1u << 2)); 60 SkASSERT(static_cast<uint32_t>(fFramebufferOnly) < (1u << 1)); 61 62 // TODO(robertphillips): not densely packed (see above asserts) 63 if (!stream->write32(static_cast<uint32_t>(fFormat))) { return false; } 64 if (!stream->write16(static_cast<uint16_t>(fUsage))) { return false; } 65 if (!stream->write8(static_cast<uint8_t>(fStorageMode))) { return false; } 66 if (!stream->write8(static_cast<uint8_t>(fFramebufferOnly))) { return false; } 67 return true; 68} 69 70bool MtlTextureInfo::deserialize(SkStream* stream) { 71 uint32_t tmp32; 72 73 if (!stream->readU32(&tmp32)) { 74 return false; 75 } 76 // TODO(robertphillips): add validity checks to deserialized values 77 fFormat = static_cast<MTLPixelFormat>(tmp32); 78 79 uint16_t tmp16; 80 if (!stream->readU16(&tmp16)) { 81 return false; 82 } 83 fUsage = static_cast<MTLTextureUsage>(tmp16); 84 85 uint8_t tmp8; 86 if (!stream->readU8(&tmp8)) { 87 return false; 88 } 89 fStorageMode = static_cast<MTLStorageMode>(tmp8); 90 91 if (!stream->readU8(&tmp8)) { 92 return false; 93 } 94 fFramebufferOnly = SkToBool(tmp8); 95 return true; 96} 97 98namespace TextureInfos { 99 100skgpu::graphite::TextureInfo MakeMetal(CFTypeRef mtlTexture) { 101 return MakeMetal(MtlTextureInfo(mtlTexture)); 102} 103 104skgpu::graphite::TextureInfo MakeMetal(const MtlTextureInfo& mtlInfo) { 105 return TextureInfoPriv::Make(mtlInfo); 106} 107 108bool GetMtlTextureInfo(const TextureInfo& info, MtlTextureInfo* out) { 109 return TextureInfoPriv::Copy(info, out); 110} 111 112} // namespace TextureInfos 113 114} // namespace skgpu::graphite 115