1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2018 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/GrStencilSettings.h" 9cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlDepthStencil.h" 10cb93a386Sopenharmony_ci#include "src/gpu/mtl/GrMtlGpu.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci#if !__has_feature(objc_arc) 13cb93a386Sopenharmony_ci#error This file must be compiled with Arc. Use -fobjc-arc flag 14cb93a386Sopenharmony_ci#endif 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ciGR_NORETAIN_BEGIN 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ciMTLStencilOperation skia_stencil_op_to_mtl(GrStencilOp op) { 19cb93a386Sopenharmony_ci switch (op) { 20cb93a386Sopenharmony_ci case GrStencilOp::kKeep: 21cb93a386Sopenharmony_ci return MTLStencilOperationKeep; 22cb93a386Sopenharmony_ci case GrStencilOp::kZero: 23cb93a386Sopenharmony_ci return MTLStencilOperationZero; 24cb93a386Sopenharmony_ci case GrStencilOp::kReplace: 25cb93a386Sopenharmony_ci return MTLStencilOperationReplace; 26cb93a386Sopenharmony_ci case GrStencilOp::kInvert: 27cb93a386Sopenharmony_ci return MTLStencilOperationInvert; 28cb93a386Sopenharmony_ci case GrStencilOp::kIncWrap: 29cb93a386Sopenharmony_ci return MTLStencilOperationIncrementWrap; 30cb93a386Sopenharmony_ci case GrStencilOp::kDecWrap: 31cb93a386Sopenharmony_ci return MTLStencilOperationDecrementWrap; 32cb93a386Sopenharmony_ci case GrStencilOp::kIncClamp: 33cb93a386Sopenharmony_ci return MTLStencilOperationIncrementClamp; 34cb93a386Sopenharmony_ci case GrStencilOp::kDecClamp: 35cb93a386Sopenharmony_ci return MTLStencilOperationDecrementClamp; 36cb93a386Sopenharmony_ci } 37cb93a386Sopenharmony_ci} 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_ciMTLStencilDescriptor* skia_stencil_to_mtl(GrStencilSettings::Face face) { 40cb93a386Sopenharmony_ci MTLStencilDescriptor* result = [[MTLStencilDescriptor alloc] init]; 41cb93a386Sopenharmony_ci switch (face.fTest) { 42cb93a386Sopenharmony_ci case GrStencilTest::kAlways: 43cb93a386Sopenharmony_ci result.stencilCompareFunction = MTLCompareFunctionAlways; 44cb93a386Sopenharmony_ci break; 45cb93a386Sopenharmony_ci case GrStencilTest::kNever: 46cb93a386Sopenharmony_ci result.stencilCompareFunction = MTLCompareFunctionNever; 47cb93a386Sopenharmony_ci break; 48cb93a386Sopenharmony_ci case GrStencilTest::kGreater: 49cb93a386Sopenharmony_ci result.stencilCompareFunction = MTLCompareFunctionGreater; 50cb93a386Sopenharmony_ci break; 51cb93a386Sopenharmony_ci case GrStencilTest::kGEqual: 52cb93a386Sopenharmony_ci result.stencilCompareFunction = MTLCompareFunctionGreaterEqual; 53cb93a386Sopenharmony_ci break; 54cb93a386Sopenharmony_ci case GrStencilTest::kLess: 55cb93a386Sopenharmony_ci result.stencilCompareFunction = MTLCompareFunctionLess; 56cb93a386Sopenharmony_ci break; 57cb93a386Sopenharmony_ci case GrStencilTest::kLEqual: 58cb93a386Sopenharmony_ci result.stencilCompareFunction = MTLCompareFunctionLessEqual; 59cb93a386Sopenharmony_ci break; 60cb93a386Sopenharmony_ci case GrStencilTest::kEqual: 61cb93a386Sopenharmony_ci result.stencilCompareFunction = MTLCompareFunctionEqual; 62cb93a386Sopenharmony_ci break; 63cb93a386Sopenharmony_ci case GrStencilTest::kNotEqual: 64cb93a386Sopenharmony_ci result.stencilCompareFunction = MTLCompareFunctionNotEqual; 65cb93a386Sopenharmony_ci break; 66cb93a386Sopenharmony_ci } 67cb93a386Sopenharmony_ci result.readMask = face.fTestMask; 68cb93a386Sopenharmony_ci result.writeMask = face.fWriteMask; 69cb93a386Sopenharmony_ci result.depthStencilPassOperation = skia_stencil_op_to_mtl(face.fPassOp); 70cb93a386Sopenharmony_ci result.stencilFailureOperation = skia_stencil_op_to_mtl(face.fFailOp); 71cb93a386Sopenharmony_ci return result; 72cb93a386Sopenharmony_ci} 73cb93a386Sopenharmony_ci 74cb93a386Sopenharmony_ciGrMtlDepthStencil* GrMtlDepthStencil::Create(const GrMtlGpu* gpu, 75cb93a386Sopenharmony_ci const GrStencilSettings& stencil, 76cb93a386Sopenharmony_ci GrSurfaceOrigin origin) { 77cb93a386Sopenharmony_ci MTLDepthStencilDescriptor* desc = [[MTLDepthStencilDescriptor alloc] init]; 78cb93a386Sopenharmony_ci if (!stencil.isDisabled()) { 79cb93a386Sopenharmony_ci if (stencil.isTwoSided()) { 80cb93a386Sopenharmony_ci desc.frontFaceStencil = skia_stencil_to_mtl(stencil.postOriginCCWFace(origin)); 81cb93a386Sopenharmony_ci desc.backFaceStencil = skia_stencil_to_mtl(stencil.postOriginCWFace(origin)); 82cb93a386Sopenharmony_ci } 83cb93a386Sopenharmony_ci else { 84cb93a386Sopenharmony_ci desc.frontFaceStencil = skia_stencil_to_mtl(stencil.singleSidedFace()); 85cb93a386Sopenharmony_ci desc.backFaceStencil = desc.frontFaceStencil; 86cb93a386Sopenharmony_ci } 87cb93a386Sopenharmony_ci } 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_ci return new GrMtlDepthStencil([gpu->device() newDepthStencilStateWithDescriptor: desc], 90cb93a386Sopenharmony_ci GenerateKey(stencil, origin)); 91cb93a386Sopenharmony_ci} 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_civoid skia_stencil_to_key(GrStencilSettings::Face face, GrMtlDepthStencil::Key::Face* faceKey) { 94cb93a386Sopenharmony_ci const int kPassOpShift = 3; 95cb93a386Sopenharmony_ci const int kFailOpShift = 6; 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ci faceKey->fReadMask = face.fTestMask; 98cb93a386Sopenharmony_ci faceKey->fWriteMask = face.fWriteMask; 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci SkASSERT(static_cast<int>(face.fTest) <= 7); 101cb93a386Sopenharmony_ci faceKey->fOps = static_cast<uint32_t>(face.fTest); 102cb93a386Sopenharmony_ci 103cb93a386Sopenharmony_ci SkASSERT(static_cast<int>(face.fPassOp) <= 7); 104cb93a386Sopenharmony_ci faceKey->fOps |= (static_cast<uint32_t>(face.fPassOp) << kPassOpShift); 105cb93a386Sopenharmony_ci 106cb93a386Sopenharmony_ci SkASSERT(static_cast<int>(face.fFailOp) <= 7); 107cb93a386Sopenharmony_ci faceKey->fOps |= (static_cast<uint32_t>(face.fFailOp) << kFailOpShift); 108cb93a386Sopenharmony_ci} 109cb93a386Sopenharmony_ci 110cb93a386Sopenharmony_ciGrMtlDepthStencil::Key GrMtlDepthStencil::GenerateKey(const GrStencilSettings& stencil, 111cb93a386Sopenharmony_ci GrSurfaceOrigin origin) { 112cb93a386Sopenharmony_ci Key depthStencilKey; 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_ci if (stencil.isDisabled()) { 115cb93a386Sopenharmony_ci memset(&depthStencilKey, 0, sizeof(Key)); 116cb93a386Sopenharmony_ci } else { 117cb93a386Sopenharmony_ci if (stencil.isTwoSided()) { 118cb93a386Sopenharmony_ci skia_stencil_to_key(stencil.postOriginCCWFace(origin), &depthStencilKey.fFront); 119cb93a386Sopenharmony_ci skia_stencil_to_key(stencil.postOriginCWFace(origin), &depthStencilKey.fBack); 120cb93a386Sopenharmony_ci } 121cb93a386Sopenharmony_ci else { 122cb93a386Sopenharmony_ci skia_stencil_to_key(stencil.singleSidedFace(), &depthStencilKey.fFront); 123cb93a386Sopenharmony_ci memcpy(&depthStencilKey.fBack, &depthStencilKey.fFront, sizeof(Key::Face)); 124cb93a386Sopenharmony_ci } 125cb93a386Sopenharmony_ci } 126cb93a386Sopenharmony_ci 127cb93a386Sopenharmony_ci return depthStencilKey; 128cb93a386Sopenharmony_ci} 129cb93a386Sopenharmony_ci 130cb93a386Sopenharmony_ciGR_NORETAIN_END 131