aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkLinearBitmapPipeline.h
blob: a6a84b5c8c983c40f6f747896e8ae2ce46339f95 (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
/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkLinearBitmapPipeline_DEFINED
#define SkLinearBitmapPipeline_DEFINED

#include "SkColor.h"
#include "SkImageInfo.h"
#include "SkMatrix.h"
#include "SkShader.h"

class SkLinearBitmapPipeline {
public:
    SkLinearBitmapPipeline(
        const SkMatrix& inverse,
        SkFilterQuality filterQuality,
        SkShader::TileMode xTile, SkShader::TileMode yTile,
        float postAlpha,
        const SkPixmap& srcPixmap);



    static bool ClonePipelineForBlitting(
        void* blitterStorage,
        const SkLinearBitmapPipeline& pipeline,
        SkMatrix::TypeMask matrixMask,
        SkShader::TileMode xTileMode,
        SkShader::TileMode yTileMode,
        SkFilterQuality filterQuality,
        const SkPixmap& srcPixmap,
        float finalAlpha,
        SkXfermode::Mode xferMode,
        const SkImageInfo& dstInfo);

    ~SkLinearBitmapPipeline();

    void shadeSpan4f(int x, int y, SkPM4f* dst, int count);
    void blitSpan(int32_t x, int32_t y, void* dst, int count);

    template<typename Base, size_t kSize, typename Next = void>
    class Stage {
    public:
        Stage() : fIsInitialized{false} {}
        ~Stage();

        template<typename Variant, typename... Args>
        void initStage(Next* next, Args&& ... args);

        template<typename Variant, typename... Args>
        void initSink(Args&& ... args);

        template <typename To, typename From>
        To* getInterface();

        // Copy this stage to `cloneToStage` with `next` as its next stage
        // (not necessarily the same as our next, you see), returning `cloneToStage`.
        // Note: There is no cloneSinkTo method because the code usually places the top part of
        // the pipeline on a new sampler.
        Base* cloneStageTo(Next* next, Stage* cloneToStage) const;

        Base* get() const { return reinterpret_cast<Base*>(&fSpace); }
        Base* operator->() const { return this->get(); }
        Base& operator*() const { return *(this->get()); }

    private:
        std::function<void (Next*, void*)> fStageCloner;
        struct SK_STRUCT_ALIGN(16) Space {
            char space[kSize];
        };
        bool fIsInitialized;
        mutable Space fSpace;
    };

    class PointProcessorInterface;
    class SampleProcessorInterface;
    class BlendProcessorInterface;
    class DestinationInterface;

    // These values were generated by the assert above in Stage::init{Sink|Stage}.
    using MatrixStage  = Stage<PointProcessorInterface,  160, PointProcessorInterface>;
    using TileStage    = Stage<PointProcessorInterface,  160, SampleProcessorInterface>;
    using SampleStage  = Stage<SampleProcessorInterface, 100, BlendProcessorInterface>;
    using BlenderStage = Stage<BlendProcessorInterface,   40>;

private:
    SkLinearBitmapPipeline(
        const SkLinearBitmapPipeline& pipeline,
        const SkPixmap& srcPixmap,
        SkXfermode::Mode xferMode,
        const SkImageInfo& dstInfo);

    PointProcessorInterface* fFirstStage;
    MatrixStage              fMatrixStage;
    TileStage                fTileStage;
    SampleStage              fSampleStage;
    BlenderStage             fBlenderStage;
    DestinationInterface*    fLastStage;
};

#endif  // SkLinearBitmapPipeline_DEFINED