Coverage Report

Created: 2021-08-22 09:07

/src/skia/src/shaders/SkColorFilterShader.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2013 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 "include/core/SkShader.h"
9
#include "include/core/SkString.h"
10
#include "src/core/SkArenaAlloc.h"
11
#include "src/core/SkColorFilterBase.h"
12
#include "src/core/SkRasterPipeline.h"
13
#include "src/core/SkReadBuffer.h"
14
#include "src/core/SkVM.h"
15
#include "src/core/SkWriteBuffer.h"
16
#include "src/shaders/SkColorFilterShader.h"
17
18
#if SK_SUPPORT_GPU
19
#include "src/gpu/GrFragmentProcessor.h"
20
#endif
21
22
SkColorFilterShader::SkColorFilterShader(sk_sp<SkShader> shader,
23
                                         float alpha,
24
                                         sk_sp<SkColorFilter> filter)
25
    : fShader(std::move(shader))
26
    , fFilter(as_CFB_sp(std::move(filter)))
27
    , fAlpha (alpha)
28
55.3k
{
29
55.3k
    SkASSERT(fShader);
30
55.3k
    SkASSERT(fFilter);
31
55.3k
}
32
33
141
sk_sp<SkFlattenable> SkColorFilterShader::CreateProc(SkReadBuffer& buffer) {
34
141
    auto shader = buffer.readShader();
35
141
    auto filter = buffer.readColorFilter();
36
141
    if (!shader || !filter) {
37
141
        return nullptr;
38
141
    }
39
0
    return sk_make_sp<SkColorFilterShader>(shader, 1.0f, filter);
40
0
}
41
42
53.3k
bool SkColorFilterShader::isOpaque() const {
43
53.3k
    return fShader->isOpaque() && fAlpha == 1.0f && as_CFB(fFilter)->isAlphaUnchanged();
44
53.3k
}
45
46
0
void SkColorFilterShader::flatten(SkWriteBuffer& buffer) const {
47
0
    buffer.writeFlattenable(fShader.get());
48
0
    SkASSERT(fAlpha == 1.0f);  // Not exposed in public API SkShader::makeWithColorFilter().
49
0
    buffer.writeFlattenable(fFilter.get());
50
0
}
Unexecuted instantiation: SkColorFilterShader::flatten(SkWriteBuffer&) const
Unexecuted instantiation: SkColorFilterShader::flatten(SkWriteBuffer&) const
51
52
5.64k
bool SkColorFilterShader::onAppendStages(const SkStageRec& rec) const {
53
5.64k
    if (!as_SB(fShader)->appendStages(rec)) {
54
294
        return false;
55
294
    }
56
5.35k
    if (fAlpha != 1.0f) {
57
3.37k
        rec.fPipeline->append(SkRasterPipeline::scale_1_float, rec.fAlloc->make<float>(fAlpha));
58
3.37k
    }
59
5.35k
    if (!fFilter->appendStages(rec, fShader->isOpaque())) {
60
340
        return false;
61
340
    }
62
5.01k
    return true;
63
5.01k
}
64
65
skvm::Color SkColorFilterShader::onProgram(skvm::Builder* p,
66
                                           skvm::Coord device, skvm::Coord local, skvm::Color paint,
67
                                           const SkMatrixProvider& matrices, const SkMatrix* localM,
68
                                           const SkColorInfo& dst,
69
50.0k
                                           skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const {
70
    // Run the shader.
71
50.0k
    skvm::Color c = as_SB(fShader)->program(p, device,local, paint,
72
50.0k
                                            matrices,localM, dst,
73
50.0k
                                            uniforms,alloc);
74
50.0k
    if (!c) {
75
49.8k
        return {};
76
49.8k
    }
77
    // Scale that by alpha.
78
233
    if (fAlpha != 1.0f) {
79
216
        skvm::F32 A = p->uniformF(uniforms->pushF(fAlpha));
80
216
        c.r *= A;
81
216
        c.g *= A;
82
216
        c.b *= A;
83
216
        c.a *= A;
84
216
    }
85
86
    // Finally run that through the color filter.
87
233
    return fFilter->program(p,c, dst, uniforms,alloc);
88
233
}
89
90
#if SK_SUPPORT_GPU
91
/////////////////////////////////////////////////////////////////////
92
93
94
std::unique_ptr<GrFragmentProcessor> SkColorFilterShader::asFragmentProcessor(
95
134
        const GrFPArgs& args) const {
96
134
    auto shaderFP = as_SB(fShader)->asFragmentProcessor(args);
97
134
    if (!shaderFP) {
98
0
        return nullptr;
99
0
    }
100
101
    // TODO I guess, but it shouldn't come up as used today.
102
134
    SkASSERT(fAlpha == 1.0f);
103
104
134
    auto [success, fp] = fFilter->asFragmentProcessor(std::move(shaderFP), args.fContext,
105
134
                                                      *args.fDstColorInfo);
106
    // If the filter FP could not be created, we still want to return the shader FP, so checking
107
    // success can be omitted here.
108
134
    return std::move(fp);
109
134
}
110
#endif
111
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113
114
645
sk_sp<SkShader> SkShader::makeWithColorFilter(sk_sp<SkColorFilter> filter) const {
115
645
    SkShader* base = const_cast<SkShader*>(this);
116
645
    if (!filter) {
117
307
        return sk_ref_sp(base);
118
307
    }
119
338
    return sk_make_sp<SkColorFilterShader>(sk_ref_sp(base), 1.0f, filter);
120
338
}