1 /*
2  * Copyright 2012 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 #ifndef SkLinearGradient_DEFINED
9 #define SkLinearGradient_DEFINED
10 
11 #include "SkGradientShaderPriv.h"
12 #include "SkNx.h"
13 
14 struct Sk4fStorage {
15     float fArray[4];
16 
Sk4fSk4fStorage17     operator Sk4f() const {
18         return Sk4f::Load(fArray);
19     }
20 
21     Sk4fStorage& operator=(const Sk4f& src) {
22         src.store(fArray);
23         return *this;
24     }
25 };
26 
27 class SkLinearGradient : public SkGradientShaderBase {
28 public:
29     enum {
30         // Temp flag for testing the 4f impl.
31         kForce4fContext_PrivateFlag     = 1 << 7,
32     };
33 
34     SkLinearGradient(const SkPoint pts[2], const Descriptor&);
35 
36     class LinearGradientContext : public SkGradientShaderBase::GradientShaderBaseContext {
37     public:
38         LinearGradientContext(const SkLinearGradient&, const ContextRec&);
39 
40         void shadeSpan(int x, int y, SkPMColor dstC[], int count) override;
41 
42         struct Rec {
43             Sk4fStorage fColor;
44             float       fPos;
45             float       fPosScale;
46         };
47     private:
48         SkTDArray<Rec>  fRecs;
49         bool            fApplyAlphaAfterInterp;
50 
51         void shade4_clamp(int x, int y, SkPMColor dstC[], int count);
52         template <bool, bool> void shade4_dx_clamp(SkPMColor dstC[], int count, float fx, float dx,
53                                                    float invDx, const float dither[2]);
54 
55         typedef SkGradientShaderBase::GradientShaderBaseContext INHERITED;
56     };
57 
58     GradientType asAGradient(GradientInfo* info) const override;
59 #if SK_SUPPORT_GPU
60     sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override;
61 #endif
62 
63     SK_TO_STRING_OVERRIDE()
64     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLinearGradient)
65 
66 protected:
67     SkLinearGradient(SkReadBuffer& buffer);
68     void flatten(SkWriteBuffer& buffer) const override;
69     Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
70 
71     bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
72                         const SkMatrix&, const SkPaint&, const SkMatrix*) const override;
73 
74 private:
75     class LinearGradient4fContext;
76 
77     friend class SkGradientShader;
78     typedef SkGradientShaderBase INHERITED;
79     const SkPoint fStart;
80     const SkPoint fEnd;
81 };
82 
83 #endif
84