1bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita/*
2bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita * Copyright 2016 Google Inc.
3bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita *
4bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita * Use of this source code is governed by a BSD-style license that can be
5bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita * found in the LICENSE file.
6bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita */
7bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita
8bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita#ifndef Sk4fGradientBase_DEFINED
9bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita#define Sk4fGradientBase_DEFINED
10bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita
11a928b288b3001eb34cc3c9caedbaac9a403b05edfmalita#include "Sk4fGradientPriv.h"
12bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita#include "SkColor.h"
13bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita#include "SkGradientShaderPriv.h"
14bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita#include "SkMatrix.h"
15bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita#include "SkNx.h"
16bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita#include "SkPM4f.h"
17bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita#include "SkShader.h"
18bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita#include "SkTArray.h"
19bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita
20da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malitastruct Sk4fGradientInterval {
21da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    Sk4fGradientInterval(const Sk4f& c0, SkScalar p0,
22da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita                         const Sk4f& c1, SkScalar p1);
23da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita
24da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    bool contains(SkScalar t) const {
25da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita        // True if t is in [p0,p1].  Note: this helper assumes a
26da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita        // natural/increasing interval - so it's not usable in Sk4fLinearGradient.
27da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita        SkASSERT(fP0 < fP1);
28da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita        return t >= fP0 && t <= fP1;
29da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    }
30da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita
31da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    SkPM4f   fC0, fDc;
32da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    SkScalar fP0, fP1;
33da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    bool     fZeroRamp;
34da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita};
35da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita
36da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malitaclass Sk4fGradientIntervalBuffer {
37da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malitapublic:
38da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    void init(const SkColor colors[], const SkScalar pos[], int count,
39da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita              SkShader::TileMode tileMode, bool premulColors, SkScalar alpha, bool reverse);
40da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita
41da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    const Sk4fGradientInterval* find(SkScalar t) const;
42da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    const Sk4fGradientInterval* findNext(SkScalar t, const Sk4fGradientInterval* prev,
43da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita                                         bool increasing) const;
44da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita
45da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    using BufferType = SkSTArray<8, Sk4fGradientInterval, true>;
46da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita
47da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    const BufferType* operator->() const { return &fIntervals; }
48da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita
49da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malitaprivate:
50da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    BufferType fIntervals;
51da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita};
52da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita
53bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalitaclass SkGradientShaderBase::
54bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalitaGradientShaderBase4fContext : public SkShader::Context {
55bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalitapublic:
56bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita    GradientShaderBase4fContext(const SkGradientShaderBase&,
57bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita                                const ContextRec&);
58bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita
59bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita    uint32_t getFlags() const override { return fFlags; }
60bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita
617e6fcf890a1a63249136b8e6d9f4d5a606ef7508fmalita    void shadeSpan(int x, int y, SkPMColor dst[], int count) override;
627e6fcf890a1a63249136b8e6d9f4d5a606ef7508fmalita    void shadeSpan4f(int x, int y, SkPM4f dst[], int count) override;
637e6fcf890a1a63249136b8e6d9f4d5a606ef7508fmalita
64088e21ba652ceaa4abb4ba8cdd2ec1bc8afc32edfmalita    bool isValid() const;
65088e21ba652ceaa4abb4ba8cdd2ec1bc8afc32edfmalita
66bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalitaprotected:
677e6fcf890a1a63249136b8e6d9f4d5a606ef7508fmalita    virtual void mapTs(int x, int y, SkScalar ts[], int count) const = 0;
687e6fcf890a1a63249136b8e6d9f4d5a606ef7508fmalita
69da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    Sk4fGradientIntervalBuffer fIntervals;
70da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    SkMatrix                   fDstToPos;
71da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    SkMatrix::MapXYProc        fDstToPosProc;
72da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    uint8_t                    fDstToPosClass;
73da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    uint8_t                    fFlags;
74da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    bool                       fDither;
75da4545bfc58f8ec19df79f6ae75b7231477973d8Florin Malita    bool                       fColorsArePremul;
76bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita
77bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalitaprivate:
78bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita    using INHERITED = SkShader::Context;
797e6fcf890a1a63249136b8e6d9f4d5a606ef7508fmalita
807e6fcf890a1a63249136b8e6d9f4d5a606ef7508fmalita    void addMirrorIntervals(const SkGradientShaderBase&,
817e6fcf890a1a63249136b8e6d9f4d5a606ef7508fmalita                            const Sk4f& componentScale, bool reverse);
827e6fcf890a1a63249136b8e6d9f4d5a606ef7508fmalita
833a2e45a6ed50c07cb1a710d3f7b74be796e61251fmalita    template<DstType, ApplyPremul, SkShader::TileMode tileMode>
847e6fcf890a1a63249136b8e6d9f4d5a606ef7508fmalita    class TSampler;
857e6fcf890a1a63249136b8e6d9f4d5a606ef7508fmalita
86dc6c9bf91c158e89cd9d5ef19dfbf1da98c598a6fmalita    template <DstType dstType, ApplyPremul premul>
87dc6c9bf91c158e89cd9d5ef19dfbf1da98c598a6fmalita    void shadePremulSpan(int x, int y, typename DstTraits<dstType, premul>::Type[],
88dc6c9bf91c158e89cd9d5ef19dfbf1da98c598a6fmalita                         int count) const;
897e6fcf890a1a63249136b8e6d9f4d5a606ef7508fmalita
90dc6c9bf91c158e89cd9d5ef19dfbf1da98c598a6fmalita    template <DstType dstType, ApplyPremul premul, SkShader::TileMode tileMode>
91dc6c9bf91c158e89cd9d5ef19dfbf1da98c598a6fmalita    void shadeSpanInternal(int x, int y, typename DstTraits<dstType, premul>::Type[],
92dc6c9bf91c158e89cd9d5ef19dfbf1da98c598a6fmalita                           int count) const;
93bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita};
94bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita
95bc590c01b00ef79e1e1f30058e7a70a29419f2a9fmalita#endif // Sk4fGradientBase_DEFINED
96