39#import <Metal/Metal.h>
46 size_t resourceBudget)
47 :
ResourceProvider(sharedContext, singleOwner, recorderID, resourceBudget) {}
55 uint64_t renderPassKey =
59 static const char* kLoadMSAAShaderText = R
"(
60 #include <metal_stdlib>
61 #include <simd/simd.h>
62 using namespace metal;
65 float4 position [[position]];
68 vertex VertexOutput vertexMain(uint vertexID [[vertex_id]]) {
70 float2 position = float2(float(vertexID >> 1), float(vertexID & 1));
71 out.position = float4(2.0 * position - 1.0, 0.0, 1.0);
75 fragment float4 fragmentMain(VertexOutput in [[stage_in]],
76 texture2d<half> colorMap [[texture(0)]]) {
77 uint2 coords = uint2(in.position.x, in.position.y);
78 half4 colorSample = colorMap.read(coords);
79 return float4(colorSample);
84 "LoadMSAAFromResolve",
88 sk_cfp<id<MTLDepthStencilState>> ignoreDS =
89 this->findOrCreateCompatibleDepthStencilState({});
91 std::string pipelineLabel =
"LoadMSAAFromResolve + ";
95 {mtlLibrary.get(),
"vertexMain"},
98 {mtlLibrary.get(),
"fragmentMain"},
105 fLoadMSAAPipelines.set(renderPassKey, pipeline);
116 std::string vsMSL, fsMSL;
137 std::string& fsSkSL = fsSkSLInfo.
fSkSL;
154 const std::string& vsSkSL = vsSkSLInfo.fSkSL;
166 this->mtlSharedContext(), vsSkSLInfo.fLabel, vsMSL, errorHandler);
168 this->mtlSharedContext(), fsSkSLInfo.
fLabel, fsMSL, errorHandler);
170 sk_cfp<id<MTLDepthStencilState>> dss =
171 this->findOrCreateCompatibleDepthStencilState(
step->depthStencilSettings());
173#if defined(GRAPHITE_TEST_UTILS)
174 GraphicsPipeline::PipelineInfo pipelineInfo = {pipelineDesc.
renderStepID(),
180 GraphicsPipeline::PipelineInfo* pipelineInfoPtr = &pipelineInfo;
182 GraphicsPipeline::PipelineInfo* pipelineInfoPtr =
nullptr;
184 std::string pipelineLabel =
188 {vsLibrary.get(),
"vertexMain"},
189 step->vertexAttributes(),
190 step->instanceAttributes(),
191 {fsLibrary.get(),
"fragmentMain"},
193 step->depthStencilSettings().fStencilReferenceValue,
200 const ComputePipelineDesc& pipelineDesc) {
201 sk_cfp<id<MTLLibrary>> library;
202 std::string entryPointName;
204 if (pipelineDesc.computeStep()->supportsNativeShader()) {
205 auto nativeShader = pipelineDesc.computeStep()->nativeShaderSource(
208 pipelineDesc.computeStep()->name(),
209 nativeShader.fSource,
211 if (library == nil) {
214 entryPointName = std::move(nativeShader.fEntryPoint);
232 pipelineDesc.computeStep()->name(),
235 entryPointName =
"computeMain";
238 pipelineDesc.computeStep()->name(),
239 {library.get(), std::move(entryPointName)});
243 const TextureInfo&
info,
249 CFTypeRef mtlHandleTexture =
texture.getMtlTexture();
250 if (!mtlHandleTexture) {
253 sk_cfp<id<MTLTexture>> mtlTexture = sk_ret_cfp((id<MTLTexture>)mtlHandleTexture);
255 std::move(mtlTexture));
264sk_sp<Sampler> MtlResourceProvider::createSampler(
const SamplerDesc& samplerDesc) {
266 samplerDesc.samplingOptions(),
267 samplerDesc.tileModeX(),
268 samplerDesc.tileModeY());
272MTLCompareFunction compare_op_to_mtl(
CompareOp op) {
275 return MTLCompareFunctionAlways;
277 return MTLCompareFunctionNever;
279 return MTLCompareFunctionGreater;
281 return MTLCompareFunctionGreaterEqual;
283 return MTLCompareFunctionLess;
285 return MTLCompareFunctionLessEqual;
287 return MTLCompareFunctionEqual;
289 return MTLCompareFunctionNotEqual;
293MTLStencilOperation stencil_op_to_mtl(
StencilOp op) {
296 return MTLStencilOperationKeep;
298 return MTLStencilOperationZero;
300 return MTLStencilOperationReplace;
302 return MTLStencilOperationInvert;
304 return MTLStencilOperationIncrementWrap;
306 return MTLStencilOperationDecrementWrap;
308 return MTLStencilOperationIncrementClamp;
310 return MTLStencilOperationDecrementClamp;
314MTLStencilDescriptor* stencil_face_to_mtl(DepthStencilSettings::Face face) {
315 MTLStencilDescriptor*
result = [[MTLStencilDescriptor alloc]
init];
316 result.stencilCompareFunction = compare_op_to_mtl(face.fCompareOp);
317 result.readMask = face.fReadMask;
318 result.writeMask = face.fWriteMask;
319 result.depthStencilPassOperation = stencil_op_to_mtl(face.fDepthStencilPassOp);
320 result.stencilFailureOperation = stencil_op_to_mtl(face.fStencilFailOp);
325sk_cfp<id<MTLDepthStencilState>> MtlResourceProvider::findOrCreateCompatibleDepthStencilState(
326 const DepthStencilSettings& depthStencilSettings) {
327 sk_cfp<id<MTLDepthStencilState>>* depthStencilState;
328 depthStencilState = fDepthStencilStates.find(depthStencilSettings);
329 if (!depthStencilState) {
330 MTLDepthStencilDescriptor*
desc = [[MTLDepthStencilDescriptor alloc]
init];
331 SkASSERT(depthStencilSettings.fDepthTestEnabled ||
333 desc.depthCompareFunction = compare_op_to_mtl(depthStencilSettings.fDepthCompareOp);
334 if (depthStencilSettings.fDepthTestEnabled) {
335 desc.depthWriteEnabled = depthStencilSettings.fDepthWriteEnabled;
337 if (depthStencilSettings.fStencilTestEnabled) {
338 desc.frontFaceStencil = stencil_face_to_mtl(depthStencilSettings.fFrontStencil);
339 desc.backFaceStencil = stencil_face_to_mtl(depthStencilSettings.fBackStencil);
342 sk_cfp<id<MTLDepthStencilState>> dss(
343 [this->mtlSharedContext()->
device() newDepthStencilStateWithDescriptor:
desc]);
344 depthStencilState = fDepthStencilStates.set(depthStencilSettings, std::move(dss));
348 return *depthStencilState;
351BackendTexture MtlResourceProvider::onCreateBackendTexture(
SkISize dimensions,
352 const TextureInfo&
info) {
359 return BackendTexture(dimensions, (CFTypeRef)
texture.release());
362void MtlResourceProvider::onDeleteBackendTexture(
const BackendTexture&
texture) {
364 CFTypeRef texHandle =
texture.getMtlTexture();
365 SkCFSafeRelease(texHandle);
static int step(int x, SkScalar min, SkScalar max)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
const char * c_str() const
skgpu::ShaderErrorHandler * shaderErrorHandler() const
const ResourceBindingRequirements & resourceBindingRequirements() const
bool storageBufferPreferred() const
const SkSL::ShaderCaps * shaderCaps() const
UniquePaintParamsID paintParamsID() const
uint32_t renderStepID() const
static sk_sp< Buffer > Make(const MtlSharedContext *, size_t size, BufferType type, AccessPattern)
uint64_t getRenderPassDescKey(const RenderPassDesc &) const
static sk_sp< MtlComputePipeline > Make(const MtlSharedContext *, const std::string &label, MSLFunction computeMain)
static sk_sp< MtlGraphicsPipeline > Make(const MtlSharedContext *, const std::string &label, MSLFunction vertexMain, SkSpan< const Attribute > vertexAttrs, SkSpan< const Attribute > instanceAttrs, MSLFunction fragmentMain, sk_cfp< id< MTLDepthStencilState > >, uint32_t stencilRefValue, const BlendInfo &blendInfo, const RenderPassDesc &, PipelineInfo *pipelineInfo)
sk_sp< MtlGraphicsPipeline > findOrCreateLoadMSAAPipeline(const RenderPassDesc &)
MtlResourceProvider(SharedContext *sharedContext, SingleOwner *, uint32_t recorderID, size_t resourceBudget)
static sk_sp< MtlSampler > Make(const MtlSharedContext *, const SkSamplingOptions &samplingOptions, SkTileMode xTileMode, SkTileMode yTileMode)
const MtlCaps & mtlCaps() const
static sk_sp< Texture > Make(const MtlSharedContext *, SkISize dimensions, const TextureInfo &, skgpu::Budgeted)
static sk_cfp< id< MTLTexture > > MakeMtlTexture(const MtlSharedContext *, SkISize dimensions, const TextureInfo &)
static sk_sp< Texture > MakeWrapped(const MtlSharedContext *, SkISize dimensions, const TextureInfo &, sk_cfp< id< MTLTexture > >)
const RenderStep * lookup(uint32_t uniqueID) const
SharedContext * fSharedContext
const Caps * caps() const
ShaderCodeDictionary * shaderCodeDictionary()
const RendererProvider * rendererProvider() const
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
VertSkSLInfo BuildVertexSkSL(const ResourceBindingRequirements &bindingReqs, const RenderStep *step, bool useStorageBuffers, bool defineLocalCoordsVarying)
std::string BuildComputeSkSL(const Caps *caps, const ComputeStep *step)
FragSkSLInfo BuildFragmentSkSL(const Caps *caps, const ShaderCodeDictionary *dict, const RuntimeEffectDictionary *rteDict, const RenderStep *step, UniquePaintParamsID paintID, bool useStorageBuffers, skgpu::Swizzle writeSwizzle)
std::string GetPipelineLabel(const ShaderCodeDictionary *dict, const RenderPassDesc &renderPassDesc, const RenderStep *renderStep, UniquePaintParamsID paintID)
sk_cfp< id< MTLLibrary > > MtlCompileShaderLibrary(const MtlSharedContext *sharedContext, std::string_view label, std::string_view msl, ShaderErrorHandler *errorHandler)
bool SkSLToMSL(const SkSL::ShaderCaps *caps, const std::string &sksl, SkSL::ProgramKind programKind, const SkSL::ProgramSettings &settings, std::string *msl, SkSL::ProgramInterface *outInterface, ShaderErrorHandler *errorHandler)
bool fRequiresLocalCoords
SkString toString() const