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