summaryrefslogtreecommitdiffstats
path: root/gfx/skia/skia/src/core/SkBlenderBase.h
blob: 5456be9973352ac18067e5ff81a89738710804b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
 * Copyright 2021 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkBlenderBase_DEFINED
#define SkBlenderBase_DEFINED

#include "include/core/SkBlender.h"
#include "src/base/SkArenaAlloc.h"
#include "src/core/SkVM.h"

#include <optional>

struct GrFPArgs;
class GrFragmentProcessor;
class SkColorInfo;
class SkRuntimeEffect;
struct SkStageRec;

namespace skgpu::graphite {
enum class DstColorType;
class KeyContext;
class PaintParamsKeyBuilder;
class PipelineDataGatherer;
}

/**
 * Encapsulates a blend function, including non-public APIs.
 * Blends combine a source color (the result of our paint) and destination color (from the canvas)
 * into a final color.
 */
class SkBlenderBase : public SkBlender {
public:
    /**
     * Returns true if this SkBlender represents any SkBlendMode, and returns the blender's
     * SkBlendMode in `mode`. Returns false for other types of blends.
     */
    virtual std::optional<SkBlendMode> asBlendMode() const { return {}; }

    SK_WARN_UNUSED_RESULT bool appendStages(const SkStageRec& rec) const {
        return this->onAppendStages(rec);
    }

    SK_WARN_UNUSED_RESULT
    virtual bool onAppendStages(const SkStageRec& rec) const = 0;

    /** Creates the blend program in SkVM. */
    SK_WARN_UNUSED_RESULT
    skvm::Color program(skvm::Builder* p, skvm::Color src, skvm::Color dst,
                        const SkColorInfo& colorInfo, skvm::Uniforms* uniforms,
                        SkArenaAlloc* alloc) const {
        return this->onProgram(p, src, dst, colorInfo, uniforms, alloc);
    }

#if defined(SK_GANESH)
    /**
     * Returns a GrFragmentProcessor that implements this blend for the GPU backend.
     * The GrFragmentProcessor expects premultiplied inputs and returns a premultiplied output.
     */
    virtual std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(
            std::unique_ptr<GrFragmentProcessor> srcFP,
            std::unique_ptr<GrFragmentProcessor> dstFP,
            const GrFPArgs& fpArgs) const = 0;
#endif

    virtual SkRuntimeEffect* asRuntimeEffect() const { return nullptr; }

#if defined(SK_GRAPHITE)
    /**
     * TODO: Make pure virtual.
     * dstColorType = kPrimitive when blending the result of the paint evaluation with a primitive
     * color (which is supplied by certain geometries). dstColorType = kSurface when blending the
     * result of the paint evaluation with the back buffer.
     */
    virtual void addToKey(const skgpu::graphite::KeyContext&,
                          skgpu::graphite::PaintParamsKeyBuilder*,
                          skgpu::graphite::PipelineDataGatherer*,
                          skgpu::graphite::DstColorType dstColorType) const;
#endif

    static SkFlattenable::Type GetFlattenableType() { return kSkBlender_Type; }
    Type getFlattenableType() const override { return GetFlattenableType(); }

private:
    virtual skvm::Color onProgram(skvm::Builder* p, skvm::Color src, skvm::Color dst,
                                  const SkColorInfo& colorInfo, skvm::Uniforms* uniforms,
                                  SkArenaAlloc* alloc) const = 0;

    using INHERITED = SkFlattenable;
};

inline SkBlenderBase* as_BB(SkBlender* blend) {
    return static_cast<SkBlenderBase*>(blend);
}

inline const SkBlenderBase* as_BB(const SkBlender* blend) {
    return static_cast<const SkBlenderBase*>(blend);
}

inline const SkBlenderBase* as_BB(const sk_sp<SkBlender>& blend) {
    return static_cast<SkBlenderBase*>(blend.get());
}

#endif  // SkBlenderBase_DEFINED