blob: 95212ce7d6881ab9228d7eeccc0c40f703ff43b3 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <Metal/Metal.h>
#include <optional>
#include "flutter/fml/build_config.h"
#include "flutter/fml/macros.h"
#include "impeller/base/validation.h"
#include "impeller/core/formats.h"
#include "impeller/core/texture_descriptor.h"
#include "impeller/geometry/color.h"
namespace impeller {
class RenderTarget;
constexpr PixelFormat FromMTLPixelFormat(MTLPixelFormat format) {
switch (format) {
case MTLPixelFormatInvalid:
return PixelFormat::kUnknown;
case MTLPixelFormatBGRA8Unorm:
return PixelFormat::kB8G8R8A8UNormInt;
case MTLPixelFormatBGRA8Unorm_sRGB:
return PixelFormat::kB8G8R8A8UNormIntSRGB;
case MTLPixelFormatRGBA8Unorm:
return PixelFormat::kR8G8B8A8UNormInt;
case MTLPixelFormatRGBA8Unorm_sRGB:
return PixelFormat::kR8G8B8A8UNormIntSRGB;
case MTLPixelFormatRGBA32Float:
return PixelFormat::kR32G32B32A32Float;
case MTLPixelFormatRGBA16Float:
return PixelFormat::kR16G16B16A16Float;
case MTLPixelFormatStencil8:
return PixelFormat::kS8UInt;
#if !FML_OS_IOS
case MTLPixelFormatDepth24Unorm_Stencil8:
return PixelFormat::kD24UnormS8Uint;
#endif // FML_OS_IOS
case MTLPixelFormatDepth32Float_Stencil8:
return PixelFormat::kD32FloatS8UInt;
case MTLPixelFormatBGR10_XR_sRGB:
return PixelFormat::kB10G10R10XRSRGB;
case MTLPixelFormatBGR10_XR:
return PixelFormat::kB10G10R10XR;
case MTLPixelFormatBGRA10_XR:
return PixelFormat::kB10G10R10A10XR;
default:
return PixelFormat::kUnknown;
}
return PixelFormat::kUnknown;
}
/// Safe accessor for MTLPixelFormatDepth24Unorm_Stencil8.
/// Returns PixelFormat::kUnknown if MTLPixelFormatDepth24Unorm_Stencil8 isn't
/// supported.
MTLPixelFormat SafeMTLPixelFormatDepth24Unorm_Stencil8();
/// Safe accessor for MTLPixelFormatBGR10_XR_sRGB.
/// Returns PixelFormat::kUnknown if MTLPixelFormatBGR10_XR_sRGB isn't
/// supported.
MTLPixelFormat SafeMTLPixelFormatBGR10_XR_sRGB();
/// Safe accessor for MTLPixelFormatBGR10_XR.
/// Returns PixelFormat::kUnknown if MTLPixelFormatBGR10_XR isn't supported.
MTLPixelFormat SafeMTLPixelFormatBGR10_XR();
/// Safe accessor for MTLPixelFormatBGRA10_XR.
/// Returns PixelFormat::kUnknown if MTLPixelFormatBGR10_XR isn't supported.
MTLPixelFormat SafeMTLPixelFormatBGRA10_XR();
constexpr MTLPixelFormat ToMTLPixelFormat(PixelFormat format) {
switch (format) {
case PixelFormat::kUnknown:
return MTLPixelFormatInvalid;
case PixelFormat::kA8UNormInt:
return MTLPixelFormatA8Unorm;
case PixelFormat::kR8UNormInt:
return MTLPixelFormatR8Unorm;
case PixelFormat::kR8G8UNormInt:
return MTLPixelFormatRG8Unorm;
case PixelFormat::kB8G8R8A8UNormInt:
return MTLPixelFormatBGRA8Unorm;
case PixelFormat::kB8G8R8A8UNormIntSRGB:
return MTLPixelFormatBGRA8Unorm_sRGB;
case PixelFormat::kR8G8B8A8UNormInt:
return MTLPixelFormatRGBA8Unorm;
case PixelFormat::kR8G8B8A8UNormIntSRGB:
return MTLPixelFormatRGBA8Unorm_sRGB;
case PixelFormat::kR32G32B32A32Float:
return MTLPixelFormatRGBA32Float;
case PixelFormat::kR16G16B16A16Float:
return MTLPixelFormatRGBA16Float;
case PixelFormat::kS8UInt:
return MTLPixelFormatStencil8;
case PixelFormat::kD24UnormS8Uint:
return SafeMTLPixelFormatDepth24Unorm_Stencil8();
case PixelFormat::kD32FloatS8UInt:
return MTLPixelFormatDepth32Float_Stencil8;
case PixelFormat::kB10G10R10XRSRGB:
return SafeMTLPixelFormatBGR10_XR_sRGB();
case PixelFormat::kB10G10R10XR:
return SafeMTLPixelFormatBGR10_XR();
case PixelFormat::kB10G10R10A10XR:
return SafeMTLPixelFormatBGRA10_XR();
}
return MTLPixelFormatInvalid;
};
constexpr MTLBlendFactor ToMTLBlendFactor(BlendFactor type) {
switch (type) {
case BlendFactor::kZero:
return MTLBlendFactorZero;
case BlendFactor::kOne:
return MTLBlendFactorOne;
case BlendFactor::kSourceColor:
return MTLBlendFactorSourceColor;
case BlendFactor::kOneMinusSourceColor:
return MTLBlendFactorOneMinusSourceColor;
case BlendFactor::kSourceAlpha:
return MTLBlendFactorSourceAlpha;
case BlendFactor::kOneMinusSourceAlpha:
return MTLBlendFactorOneMinusSourceAlpha;
case BlendFactor::kDestinationColor:
return MTLBlendFactorDestinationColor;
case BlendFactor::kOneMinusDestinationColor:
return MTLBlendFactorOneMinusDestinationColor;
case BlendFactor::kDestinationAlpha:
return MTLBlendFactorDestinationAlpha;
case BlendFactor::kOneMinusDestinationAlpha:
return MTLBlendFactorOneMinusDestinationAlpha;
case BlendFactor::kSourceAlphaSaturated:
return MTLBlendFactorSourceAlphaSaturated;
case BlendFactor::kBlendColor:
return MTLBlendFactorBlendColor;
case BlendFactor::kOneMinusBlendColor:
return MTLBlendFactorOneMinusBlendColor;
case BlendFactor::kBlendAlpha:
return MTLBlendFactorBlendAlpha;
case BlendFactor::kOneMinusBlendAlpha:
return MTLBlendFactorOneMinusBlendAlpha;
}
return MTLBlendFactorZero;
};
constexpr MTLPrimitiveType ToMTLPrimitiveType(PrimitiveType type) {
switch (type) {
case PrimitiveType::kTriangle:
return MTLPrimitiveTypeTriangle;
case PrimitiveType::kTriangleStrip:
return MTLPrimitiveTypeTriangleStrip;
case PrimitiveType::kLine:
return MTLPrimitiveTypeLine;
case PrimitiveType::kLineStrip:
return MTLPrimitiveTypeLineStrip;
case PrimitiveType::kPoint:
return MTLPrimitiveTypePoint;
}
return MTLPrimitiveTypePoint;
}
constexpr MTLTriangleFillMode ToMTLTriangleFillMode(PolygonMode mode) {
switch (mode) {
case PolygonMode::kFill:
return MTLTriangleFillModeFill;
case PolygonMode::kLine:
return MTLTriangleFillModeLines;
}
return MTLTriangleFillModeFill;
}
constexpr MTLIndexType ToMTLIndexType(IndexType type) {
switch (type) {
case IndexType::k16bit:
return MTLIndexTypeUInt16;
default:
return MTLIndexTypeUInt32;
}
}
constexpr MTLCullMode ToMTLCullMode(CullMode mode) {
switch (mode) {
case CullMode::kNone:
return MTLCullModeNone;
case CullMode::kBackFace:
return MTLCullModeBack;
case CullMode::kFrontFace:
return MTLCullModeFront;
}
return MTLCullModeNone;
}
constexpr MTLBlendOperation ToMTLBlendOperation(BlendOperation type) {
switch (type) {
case BlendOperation::kAdd:
return MTLBlendOperationAdd;
case BlendOperation::kSubtract:
return MTLBlendOperationSubtract;
case BlendOperation::kReverseSubtract:
return MTLBlendOperationReverseSubtract;
}
return MTLBlendOperationAdd;
};
constexpr MTLColorWriteMask ToMTLColorWriteMask(
std::underlying_type_t<ColorWriteMask> type) {
using UnderlyingType = decltype(type);
MTLColorWriteMask mask = MTLColorWriteMaskNone;
if (type & static_cast<UnderlyingType>(ColorWriteMask::kRed)) {
mask |= MTLColorWriteMaskRed;
}
if (type & static_cast<UnderlyingType>(ColorWriteMask::kGreen)) {
mask |= MTLColorWriteMaskGreen;
}
if (type & static_cast<UnderlyingType>(ColorWriteMask::kBlue)) {
mask |= MTLColorWriteMaskBlue;
}
if (type & static_cast<UnderlyingType>(ColorWriteMask::kAlpha)) {
mask |= MTLColorWriteMaskAlpha;
}
return mask;
};
constexpr MTLCompareFunction ToMTLCompareFunction(CompareFunction func) {
switch (func) {
case CompareFunction::kNever:
return MTLCompareFunctionNever;
case CompareFunction::kLess:
return MTLCompareFunctionLess;
case CompareFunction::kEqual:
return MTLCompareFunctionEqual;
case CompareFunction::kLessEqual:
return MTLCompareFunctionLessEqual;
case CompareFunction::kGreater:
return MTLCompareFunctionGreater;
case CompareFunction::kNotEqual:
return MTLCompareFunctionNotEqual;
case CompareFunction::kGreaterEqual:
return MTLCompareFunctionGreaterEqual;
case CompareFunction::kAlways:
return MTLCompareFunctionAlways;
}
return MTLCompareFunctionAlways;
};
constexpr MTLStencilOperation ToMTLStencilOperation(StencilOperation op) {
switch (op) {
case StencilOperation::kKeep:
return MTLStencilOperationKeep;
case StencilOperation::kZero:
return MTLStencilOperationZero;
case StencilOperation::kSetToReferenceValue:
return MTLStencilOperationReplace;
case StencilOperation::kIncrementClamp:
return MTLStencilOperationIncrementClamp;
case StencilOperation::kDecrementClamp:
return MTLStencilOperationDecrementClamp;
case StencilOperation::kInvert:
return MTLStencilOperationInvert;
case StencilOperation::kIncrementWrap:
return MTLStencilOperationIncrementWrap;
case StencilOperation::kDecrementWrap:
return MTLStencilOperationDecrementWrap;
}
return MTLStencilOperationKeep;
};
constexpr MTLLoadAction ToMTLLoadAction(LoadAction action) {
switch (action) {
case LoadAction::kDontCare:
return MTLLoadActionDontCare;
case LoadAction::kLoad:
return MTLLoadActionLoad;
case LoadAction::kClear:
return MTLLoadActionClear;
}
return MTLLoadActionDontCare;
}
constexpr LoadAction FromMTLLoadAction(MTLLoadAction action) {
switch (action) {
case MTLLoadActionDontCare:
return LoadAction::kDontCare;
case MTLLoadActionLoad:
return LoadAction::kLoad;
case MTLLoadActionClear:
return LoadAction::kClear;
default:
break;
}
return LoadAction::kDontCare;
}
constexpr MTLStoreAction ToMTLStoreAction(StoreAction action) {
switch (action) {
case StoreAction::kDontCare:
return MTLStoreActionDontCare;
case StoreAction::kStore:
return MTLStoreActionStore;
case StoreAction::kMultisampleResolve:
return MTLStoreActionMultisampleResolve;
case StoreAction::kStoreAndMultisampleResolve:
return MTLStoreActionStoreAndMultisampleResolve;
}
return MTLStoreActionDontCare;
}
constexpr StoreAction FromMTLStoreAction(MTLStoreAction action) {
switch (action) {
case MTLStoreActionDontCare:
return StoreAction::kDontCare;
case MTLStoreActionStore:
return StoreAction::kStore;
case MTLStoreActionMultisampleResolve:
return StoreAction::kMultisampleResolve;
case MTLStoreActionStoreAndMultisampleResolve:
return StoreAction::kStoreAndMultisampleResolve;
default:
break;
}
return StoreAction::kDontCare;
}
constexpr MTLSamplerMinMagFilter ToMTLSamplerMinMagFilter(MinMagFilter filter) {
switch (filter) {
case MinMagFilter::kNearest:
return MTLSamplerMinMagFilterNearest;
case MinMagFilter::kLinear:
return MTLSamplerMinMagFilterLinear;
}
return MTLSamplerMinMagFilterNearest;
}
constexpr MTLSamplerMipFilter ToMTLSamplerMipFilter(MipFilter filter) {
switch (filter) {
case MipFilter::kNearest:
return MTLSamplerMipFilterNearest;
case MipFilter::kLinear:
return MTLSamplerMipFilterLinear;
}
return MTLSamplerMipFilterNotMipmapped;
}
constexpr MTLSamplerAddressMode ToMTLSamplerAddressMode(
SamplerAddressMode mode) {
switch (mode) {
case SamplerAddressMode::kClampToEdge:
return MTLSamplerAddressModeClampToEdge;
case SamplerAddressMode::kRepeat:
return MTLSamplerAddressModeRepeat;
case SamplerAddressMode::kMirror:
return MTLSamplerAddressModeMirrorRepeat;
case SamplerAddressMode::kDecal:
return MTLSamplerAddressModeClampToZero;
}
return MTLSamplerAddressModeClampToEdge;
}
inline MTLClearColor ToMTLClearColor(const Color& color) {
return MTLClearColorMake(color.red, color.green, color.blue, color.alpha);
}
constexpr MTLTextureType ToMTLTextureType(TextureType type) {
switch (type) {
case TextureType::kTexture2D:
return MTLTextureType2D;
case TextureType::kTexture2DMultisample:
return MTLTextureType2DMultisample;
case TextureType::kTextureCube:
return MTLTextureTypeCube;
case TextureType::kTextureExternalOES:
VALIDATION_LOG
<< "kTextureExternalOES can not be used with the Metal backend.";
}
return MTLTextureType2D;
}
MTLRenderPipelineColorAttachmentDescriptor*
ToMTLRenderPipelineColorAttachmentDescriptor(
ColorAttachmentDescriptor descriptor);
MTLDepthStencilDescriptor* ToMTLDepthStencilDescriptor(
std::optional<DepthAttachmentDescriptor> depth,
std::optional<StencilAttachmentDescriptor> front,
std::optional<StencilAttachmentDescriptor> back);
MTLTextureDescriptor* ToMTLTextureDescriptor(const TextureDescriptor& desc);
} // namespace impeller