Hash :
1bd1a3db
Author :
Date :
2022-01-06T15:08:48
Metal: Canvas resizing causes webpage to run out of memory For https://bugs.webkit.org/show_bug.cgi?id=232122 Introduce a maximum resident amount of memory that a single command buffer can use, before forcing a flush. As part of ensuring that a command buffer is ready, check to see if this limit is exceeded. if so, flush the command buffer, and create a new one. Bug: angleproject:6880 Change-Id: I5e89735d05adbc174237ab79b006a75bbe89e560 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3369922 Reviewed-by: Gregg Tavares <gman@chromium.org> Reviewed-by: Kenneth Russell <kbr@chromium.org> Commit-Queue: Kyle Piddington <kpiddington@apple.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// mtl_utils.h:
// Declares utilities functions that create Metal shaders, convert from angle enums
// to Metal enums and so on.
//
#ifndef LIBANGLE_RENDERER_METAL_MTL_UTILS_H_
#define LIBANGLE_RENDERER_METAL_MTL_UTILS_H_
#import <Metal/Metal.h>
#include "angle_gl.h"
#include "common/PackedEnums.h"
#include "libANGLE/Context.h"
#include "libANGLE/Texture.h"
#include "libANGLE/renderer/metal/mtl_format_utils.h"
#include "libANGLE/renderer/metal/mtl_resources.h"
#include "libANGLE/renderer/metal/mtl_state_cache.h"
namespace rx
{
class ContextMtl;
void StartFrameCapture(id<MTLDevice> metalDevice, id<MTLCommandQueue> metalCmdQueue);
void StartFrameCapture(ContextMtl *context);
void StopFrameCapture();
namespace mtl
{
// Initialize texture content to black.
angle::Result InitializeTextureContents(const gl::Context *context,
const TextureRef &texture,
const Format &textureObjFormat,
const ImageNativeIndex &index);
// Same as above but using GPU clear operation instead of CPU.
// - channelsToInit parameter controls which channels will get their content initialized.
angle::Result InitializeTextureContentsGPU(const gl::Context *context,
const TextureRef &texture,
const Format &textureObjFormat,
const ImageNativeIndex &index,
MTLColorWriteMask channelsToInit);
// Same as above but for a depth/stencil texture.
angle::Result InitializeDepthStencilTextureContentsGPU(const gl::Context *context,
const TextureRef &texture,
const Format &textureObjFormat,
const ImageNativeIndex &index);
// Unified texture's per slice/depth texel reading function
angle::Result ReadTexturePerSliceBytes(const gl::Context *context,
const TextureRef &texture,
size_t bytesPerRow,
const gl::Rectangle &fromRegion,
const MipmapNativeLevel &mipLevel,
uint32_t sliceOrDepth,
uint8_t *dataOut);
angle::Result ReadTexturePerSliceBytesToBuffer(const gl::Context *context,
const TextureRef &texture,
size_t bytesPerRow,
const gl::Rectangle &fromRegion,
const MipmapNativeLevel &mipLevel,
uint32_t sliceOrDepth,
uint32_t dstOffset,
const BufferRef &dstBuffer);
MTLViewport GetViewport(const gl::Rectangle &rect, double znear = 0, double zfar = 1);
MTLViewport GetViewportFlipY(const gl::Rectangle &rect,
NSUInteger screenHeight,
double znear = 0,
double zfar = 1);
MTLViewport GetViewport(const gl::Rectangle &rect,
NSUInteger screenHeight,
bool flipY,
double znear = 0,
double zfar = 1);
MTLScissorRect GetScissorRect(const gl::Rectangle &rect,
NSUInteger screenHeight = 0,
bool flipY = false);
uint32_t GetDeviceVendorId(id<MTLDevice> metalDevice);
AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary(
const mtl::ContextDevice &metalDevice,
const std::string &source,
NSDictionary<NSString *, NSObject *> *substitutionDictionary,
bool enableFastMath,
AutoObjCPtr<NSError *> *error);
AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary(const mtl::ContextDevice &metalDevice,
const std::string &source,
AutoObjCPtr<NSError *> *error);
AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary(
const mtl::ContextDevice &metalDevice,
const char *source,
size_t sourceLen,
NSDictionary<NSString *, NSObject *> *substitutionDictionary,
bool enableFastMath,
AutoObjCPtr<NSError *> *error);
AutoObjCPtr<id<MTLLibrary>> CreateShaderLibraryFromBinary(
id<MTLDevice> metalDevice,
const uint8_t *binarySource,
size_t binarySourceLen,
NSDictionary<NSString *, NSObject *> *substitutionDictionary,
AutoObjCPtr<NSError *> *error);
bool SupportsAppleGPUFamily(id<MTLDevice> device, uint8_t appleFamily);
bool SupportsMacGPUFamily(id<MTLDevice> device, uint8_t macFamily);
// Need to define invalid enum value since Metal doesn't define it
constexpr MTLTextureType MTLTextureTypeInvalid = static_cast<MTLTextureType>(NSUIntegerMax);
static_assert(sizeof(MTLTextureType) == sizeof(NSUInteger),
"MTLTextureType is supposed to be based on NSUInteger");
constexpr MTLPrimitiveType MTLPrimitiveTypeInvalid = static_cast<MTLPrimitiveType>(NSUIntegerMax);
static_assert(sizeof(MTLPrimitiveType) == sizeof(NSUInteger),
"MTLPrimitiveType is supposed to be based on NSUInteger");
constexpr MTLIndexType MTLIndexTypeInvalid = static_cast<MTLIndexType>(NSUIntegerMax);
static_assert(sizeof(MTLIndexType) == sizeof(NSUInteger),
"MTLIndexType is supposed to be based on NSUInteger");
MTLTextureType GetTextureType(gl::TextureType glType);
MTLSamplerMinMagFilter GetFilter(GLenum filter);
MTLSamplerMipFilter GetMipmapFilter(GLenum filter);
MTLSamplerAddressMode GetSamplerAddressMode(GLenum wrap);
MTLBlendFactor GetBlendFactor(GLenum factor);
MTLBlendOperation GetBlendOp(GLenum op);
MTLCompareFunction GetCompareFunc(GLenum func);
MTLStencilOperation GetStencilOp(GLenum op);
MTLWinding GetFontfaceWinding(GLenum frontFaceMode, bool invert);
PrimitiveTopologyClass GetPrimitiveTopologyClass(gl::PrimitiveMode mode);
MTLPrimitiveType GetPrimitiveType(gl::PrimitiveMode mode);
MTLIndexType GetIndexType(gl::DrawElementsType type);
#if ANGLE_MTL_SWIZZLE_AVAILABLE
MTLTextureSwizzle GetTextureSwizzle(GLenum swizzle);
#endif
// Get color write mask for a specified format. Some formats such as RGB565 doesn't have alpha
// channel but is emulated by a RGBA8 format, we need to disable alpha write for this format.
// - emulatedChannelsOut: if the format is emulated, this pointer will store a true value.
MTLColorWriteMask GetEmulatedColorWriteMask(const mtl::Format &mtlFormat,
bool *emulatedChannelsOut);
MTLColorWriteMask GetEmulatedColorWriteMask(const mtl::Format &mtlFormat);
bool IsFormatEmulated(const mtl::Format &mtlFormat);
size_t EstimateTextureSizeInBytes(const mtl::Format &mtlFormat,
size_t width,
size_t height,
size_t depth,
size_t sampleCount,
size_t numMips);
NSUInteger GetMaxRenderTargetSizeForDeviceInBytes(const mtl::ContextDevice &device);
NSUInteger GetMaxNumberOfRenderTargetsForDevice(const mtl::ContextDevice &device);
bool DeviceHasMaximumRenderTargetSize(id<MTLDevice> device);
// Useful to set clear color for texture originally having no alpha in GL, but backend's format
// has alpha channel.
MTLClearColor EmulatedAlphaClearColor(MTLClearColor color, MTLColorWriteMask colorMask);
NSUInteger ComputeTotalSizeUsedForMTLRenderPassDescriptor(const MTLRenderPassDescriptor *descriptor,
const Context *context,
const mtl::ContextDevice &device);
NSUInteger ComputeTotalSizeUsedForMTLRenderPipelineDescriptor(
const MTLRenderPipelineDescriptor *descriptor,
const Context *context,
const mtl::ContextDevice &device);
gl::Box MTLRegionToGLBox(const MTLRegion &mtlRegion);
MipmapNativeLevel GetNativeMipLevel(GLuint level, GLuint base);
GLuint GetGLMipLevel(const MipmapNativeLevel &nativeLevel, GLuint base);
angle::Result TriangleFanBoundCheck(ContextMtl *context, size_t numTris);
angle::Result GetTriangleFanIndicesCount(ContextMtl *context,
GLsizei vetexCount,
uint32_t *numElemsOut);
angle::Result CreateMslShader(Context *context,
id<MTLLibrary> shaderLib,
NSString *shaderName,
MTLFunctionConstantValues *funcConstants,
AutoObjCPtr<id<MTLFunction>> *shaderOut);
angle::Result CreateMslShader(Context *context,
id<MTLLibrary> shaderLib,
NSString *shaderName,
MTLFunctionConstantValues *funcConstants,
id<MTLFunction> *shaderOut);
} // namespace mtl
} // namespace rx
#endif /* LIBANGLE_RENDERER_METAL_MTL_UTILS_H_ */