Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / src / gpu / ganesh / ops / AtlasInstancedHelper.cpp
1 /*
2  * Copyright 2020 Google LLC.
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/ops/AtlasInstancedHelper.h"
9
10 #include "src/gpu/BufferWriter.h"
11 #include "src/gpu/KeyBuilder.h"
12 #include "src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder.h"
13 #include "src/gpu/ganesh/glsl/GrGLSLVarying.h"
14 #include "src/gpu/ganesh/glsl/GrGLSLVertexGeoBuilder.h"
15
16 namespace skgpu::v1 {
17
18 void AtlasInstancedHelper::getKeyBits(KeyBuilder* b) const {
19     b->addBits(kNumShaderFlags, (int)fShaderFlags, "atlasFlags");
20 }
21
22 void AtlasInstancedHelper::appendInstanceAttribs(
23         SkTArray<GrGeometryProcessor::Attribute>* instanceAttribs) const {
24     instanceAttribs->emplace_back("locations", kFloat4_GrVertexAttribType, SkSLType::kFloat4);
25     if (fShaderFlags & ShaderFlags::kCheckBounds) {
26         instanceAttribs->emplace_back("sizeInAtlas", kFloat2_GrVertexAttribType, SkSLType::kFloat2);
27     }
28 }
29
30 void AtlasInstancedHelper::writeInstanceData(VertexWriter* instanceWriter,
31                                              const Instance* i) const {
32     SkASSERT(i->fLocationInAtlas.x() >= 0);
33     SkASSERT(i->fLocationInAtlas.y() >= 0);
34     *instanceWriter <<
35             // A negative x coordinate in the atlas indicates that the path is transposed.
36             // Also add 1 since we can't negate zero.
37             ((float)(i->fTransposedInAtlas ? -i->fLocationInAtlas.x() - 1
38                      : i->fLocationInAtlas.x() + 1)) <<
39             (float)i->fLocationInAtlas.y() <<
40             (float)i->fPathDevIBounds.left() <<
41             (float)i->fPathDevIBounds.top() <<
42             VertexWriter::If(fShaderFlags & ShaderFlags::kCheckBounds,
43                              SkSize::Make(i->fPathDevIBounds.size()));
44 }
45
46 void AtlasInstancedHelper::injectShaderCode(
47         const GrGeometryProcessor::ProgramImpl::EmitArgs& args,
48         const GrShaderVar& devCoord,
49         GrGLSLUniformHandler::UniformHandle* atlasAdjustUniformHandle) const {
50     GrGLSLVarying atlasCoord(SkSLType::kFloat2);
51     args.fVaryingHandler->addVarying("atlasCoord", &atlasCoord);
52
53     const char* atlasAdjustName;
54     *atlasAdjustUniformHandle = args.fUniformHandler->addUniform(
55             nullptr, kVertex_GrShaderFlag, SkSLType::kFloat2, "atlas_adjust", &atlasAdjustName);
56
57     args.fVertBuilder->codeAppendf(R"(
58     // A negative x coordinate in the atlas indicates that the path is transposed.
59     // We also added 1 since we can't negate zero.
60     float2 atlasTopLeft = float2(abs(locations.x) - 1, locations.y);
61     float2 devTopLeft = locations.zw;
62     bool transposed = locations.x < 0;
63     float2 atlasCoord = %s - devTopLeft;
64     if (transposed) {
65         atlasCoord = atlasCoord.yx;
66     }
67     atlasCoord += atlasTopLeft;
68     %s = atlasCoord * %s;)", devCoord.c_str(), atlasCoord.vsOut(), atlasAdjustName);
69
70     if (fShaderFlags & ShaderFlags::kCheckBounds) {
71         GrGLSLVarying atlasBounds(SkSLType::kFloat4);
72         args.fVaryingHandler->addVarying("atlasbounds", &atlasBounds,
73                                          GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
74         args.fVertBuilder->codeAppendf(R"(
75         float4 atlasBounds = atlasTopLeft.xyxy + (transposed ? sizeInAtlas.00yx
76                                                              : sizeInAtlas.00xy);
77         %s = atlasBounds * %s.xyxy;)", atlasBounds.vsOut(), atlasAdjustName);
78
79         args.fFragBuilder->codeAppendf(R"(
80         half atlasCoverage = 0;
81         float2 atlasCoord = %s;
82         float4 atlasBounds = %s;
83         if (all(greaterThan(atlasCoord, atlasBounds.xy)) &&
84             all(lessThan(atlasCoord, atlasBounds.zw))) {
85             atlasCoverage = )", atlasCoord.fsIn(), atlasBounds.fsIn());
86         args.fFragBuilder->appendTextureLookup(args.fTexSamplers[0], "atlasCoord");
87         args.fFragBuilder->codeAppendf(R"(.a;
88         })");
89     } else {
90         args.fFragBuilder->codeAppendf("half atlasCoverage = ");
91         args.fFragBuilder->appendTextureLookup(args.fTexSamplers[0], atlasCoord.fsIn());
92         args.fFragBuilder->codeAppendf(".a;");
93     }
94
95     if (fShaderFlags & ShaderFlags::kInvertCoverage) {
96         args.fFragBuilder->codeAppendf("%s *= (1 - atlasCoverage);", args.fOutputCoverage);
97     } else {
98         args.fFragBuilder->codeAppendf("%s *= atlasCoverage;", args.fOutputCoverage);
99     }
100 }
101
102 void AtlasInstancedHelper::setUniformData(
103         const GrGLSLProgramDataManager& pdman,
104         const GrGLSLUniformHandler::UniformHandle& atlasAdjustUniformHandle) const {
105     SkASSERT(fAtlasProxy->isInstantiated());
106     SkISize dimensions = fAtlasProxy->backingStoreDimensions();
107     pdman.set2f(atlasAdjustUniformHandle, 1.f / dimensions.width(), 1.f / dimensions.height());
108 }
109
110 } // namespace skgpu::v1