Coverage Report

Created: 2024-05-20 07:14

/src/skia/src/gpu/graphite/render/BitmapTextRenderStep.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2022 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/graphite/render/BitmapTextRenderStep.h"
9
10
#include "include/core/SkM44.h"
11
#include "include/gpu/graphite/Recorder.h"
12
#include "src/gpu/graphite/AtlasProvider.h"
13
#include "src/gpu/graphite/ContextUtils.h"
14
#include "src/gpu/graphite/DrawParams.h"
15
#include "src/gpu/graphite/DrawWriter.h"
16
#include "src/gpu/graphite/PipelineData.h"
17
#include "src/gpu/graphite/RecorderPriv.h"
18
#include "src/gpu/graphite/render/CommonDepthStencilSettings.h"
19
#include "src/gpu/graphite/text/TextAtlasManager.h"
20
#include "src/sksl/SkSLString.h"
21
#include "src/text/gpu/SubRunContainer.h"
22
#include "src/text/gpu/VertexFiller.h"
23
24
using AtlasSubRun = sktext::gpu::AtlasSubRun;
25
26
namespace skgpu::graphite {
27
28
namespace {
29
30
// We are expecting to sample from up to 4 textures
31
constexpr int kNumTextAtlasTextures = 4;
32
33
}  // namespace
34
35
BitmapTextRenderStep::BitmapTextRenderStep(bool isLCD)
36
        : RenderStep("BitmapTextRenderStep",
37
                     "",
38
                     isLCD ? Flags::kPerformsShading | Flags::kHasTextures | Flags::kEmitsCoverage |
39
                             Flags::kLCDCoverage
40
                           : Flags::kPerformsShading | Flags::kHasTextures | Flags::kEmitsCoverage,
41
                     /*uniforms=*/{{"subRunDeviceMatrix", SkSLType::kFloat4x4},
42
                                   {"deviceToLocal"     , SkSLType::kFloat4x4},
43
                                   {"atlasSizeInv"      , SkSLType::kFloat2}},
44
                     PrimitiveType::kTriangleStrip,
45
                     kDirectDepthGEqualPass,
46
                     /*vertexAttrs=*/ {},
47
                     /*instanceAttrs=*/
48
                     {{"size", VertexAttribType::kUShort2, SkSLType::kUShort2},
49
                      {"uvPos", VertexAttribType::kUShort2, SkSLType::kUShort2},
50
                      {"xyPos", VertexAttribType::kFloat2, SkSLType::kFloat2},
51
                      {"indexAndFlags", VertexAttribType::kUShort2, SkSLType::kUShort2},
52
                      {"strikeToSourceScale", VertexAttribType::kFloat, SkSLType::kFloat},
53
                      {"depth", VertexAttribType::kFloat, SkSLType::kFloat},
54
                      {"ssboIndices", VertexAttribType::kUShort2, SkSLType::kUShort2}},
55
                     /*varyings=*/
56
                     {{"textureCoords", SkSLType::kFloat2},
57
                      {"texIndex", SkSLType::kHalf},
58
0
                      {"maskFormat", SkSLType::kHalf}}) {}
59
60
0
BitmapTextRenderStep::~BitmapTextRenderStep() {}
61
62
0
std::string BitmapTextRenderStep::vertexSkSL() const {
63
    // Returns the body of a vertex function, which must define a float4 devPosition variable and
64
    // must write to an already-defined float2 stepLocalCoords variable.
65
0
    return "texIndex = half(indexAndFlags.x);"
66
0
           "maskFormat = half(indexAndFlags.y);"
67
0
           "float2 unormTexCoords;"
68
0
           "float4 devPosition = text_vertex_fn(float2(sk_VertexID >> 1, sk_VertexID & 1), "
69
0
                                               "subRunDeviceMatrix, "
70
0
                                               "deviceToLocal, "
71
0
                                               "atlasSizeInv, "
72
0
                                               "float2(size), "
73
0
                                               "float2(uvPos), "
74
0
                                               "xyPos, "
75
0
                                               "strikeToSourceScale, "
76
0
                                               "depth, "
77
0
                                               "textureCoords, "
78
0
                                               "unormTexCoords, "
79
0
                                               "stepLocalCoords);";
80
0
}
81
82
std::string BitmapTextRenderStep::texturesAndSamplersSkSL(
83
0
        const ResourceBindingRequirements& bindingReqs, int* nextBindingIndex) const {
84
0
    std::string result;
85
86
0
    for (unsigned int i = 0; i < kNumTextAtlasTextures; ++i) {
87
0
        result += EmitSamplerLayout(bindingReqs, nextBindingIndex);
88
0
        SkSL::String::appendf(&result, " sampler2D text_atlas_%u;\n", i);
89
0
    }
90
91
0
    return result;
92
0
}
93
94
0
const char* BitmapTextRenderStep::fragmentCoverageSkSL() const {
95
    // The returned SkSL must write its coverage into a 'half4 outputCoverage' variable (defined in
96
    // the calling code) with the actual coverage splatted out into all four channels.
97
0
    static_assert(kNumTextAtlasTextures == 4);
98
0
    return "outputCoverage = bitmap_text_coverage_fn(sample_indexed_atlas(textureCoords, "
99
0
                                                                         "int(texIndex), "
100
0
                                                                         "text_atlas_0, "
101
0
                                                                         "text_atlas_1, "
102
0
                                                                         "text_atlas_2, "
103
0
                                                                         "text_atlas_3), "
104
0
                                                    "int(maskFormat));";
105
0
}
106
107
void BitmapTextRenderStep::writeVertices(DrawWriter* dw,
108
                                         const DrawParams& params,
109
0
                                         skvx::ushort2 ssboIndices) const {
110
0
    const SubRunData& subRunData = params.geometry().subRunData();
111
112
0
    subRunData.subRun()->vertexFiller().fillInstanceData(dw,
113
0
                                                         subRunData.startGlyphIndex(),
114
0
                                                         subRunData.glyphCount(),
115
0
                                                         subRunData.subRun()->instanceFlags(),
116
0
                                                         ssboIndices,
117
0
                                                         subRunData.subRun()->glyphs(),
118
0
                                                         params.order().depthAsFloat());
119
0
}
120
121
void BitmapTextRenderStep::writeUniformsAndTextures(const DrawParams& params,
122
0
                                                    PipelineDataGatherer* gatherer) const {
123
0
    SkDEBUGCODE(UniformExpectationsValidator uev(gatherer, this->uniforms());)
124
125
0
    const SubRunData& subRunData = params.geometry().subRunData();
126
0
    unsigned int numProxies;
127
0
    Recorder* recorder = subRunData.recorder();
128
0
    const sk_sp<TextureProxy>* proxies =
129
0
            recorder->priv().atlasProvider()->textAtlasManager()->getProxies(
130
0
                    subRunData.subRun()->maskFormat(), &numProxies);
131
0
    SkASSERT(proxies && numProxies > 0);
132
133
    // write uniforms
134
0
    gatherer->write(params.transform().matrix());  // subRunDeviceMatrix
135
0
    gatherer->write(subRunData.deviceToLocal());
136
0
    SkV2 atlasDimensionsInverse = {1.f/proxies[0]->dimensions().width(),
137
0
                                   1.f/proxies[0]->dimensions().height()};
138
0
    gatherer->write(atlasDimensionsInverse);
139
140
    // write textures and samplers
141
0
    const SkSamplingOptions kSamplingOptions(SkFilterMode::kNearest);
142
0
    constexpr SkTileMode kTileModes[2] = { SkTileMode::kClamp, SkTileMode::kClamp };
143
0
    for (unsigned int i = 0; i < numProxies; ++i) {
144
0
        gatherer->add(kSamplingOptions, kTileModes, proxies[i]);
145
0
    }
146
    // If the atlas has less than 4 active proxies we still need to set up samplers for the shader.
147
0
    for (unsigned int i = numProxies; i < kNumTextAtlasTextures; ++i) {
148
0
        gatherer->add(kSamplingOptions, kTileModes, proxies[0]);
149
0
    }
150
0
}
Unexecuted instantiation: skgpu::graphite::BitmapTextRenderStep::writeUniformsAndTextures(skgpu::graphite::DrawParams const&, skgpu::graphite::PipelineDataGatherer*) const
Unexecuted instantiation: skgpu::graphite::BitmapTextRenderStep::writeUniformsAndTextures(skgpu::graphite::DrawParams const&, skgpu::graphite::PipelineDataGatherer*) const
151
152
}  // namespace skgpu::graphite