Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / src / shaders / gradients / SkSweepGradient.cpp
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 #include "src/shaders/gradients/SkSweepGradient.h"
9
10 #include "include/private/SkFloatingPoint.h"
11 #include "src/core/SkRasterPipeline.h"
12 #include "src/core/SkReadBuffer.h"
13 #include "src/core/SkWriteBuffer.h"
14
15 #ifdef SK_ENABLE_SKSL
16 #include "src/core/SkKeyHelpers.h"
17 #endif
18
19 SkSweepGradient::SkSweepGradient(const SkPoint& center, SkScalar t0, SkScalar t1,
20                                  const Descriptor& desc)
21     : SkGradientShaderBase(desc, SkMatrix::Translate(-center.x(), -center.y()))
22     , fCenter(center)
23     , fTBias(-t0)
24     , fTScale(1 / (t1 - t0))
25 {
26     SkASSERT(t0 < t1);
27 }
28
29 SkShader::GradientType SkSweepGradient::asAGradient(GradientInfo* info) const {
30     if (info) {
31         commonAsAGradient(info);
32         info->fPoint[0] = fCenter;
33     }
34     return kSweep_GradientType;
35 }
36
37 static std::tuple<SkScalar, SkScalar> angles_from_t_coeff(SkScalar tBias, SkScalar tScale) {
38     return std::make_tuple(-tBias * 360, (sk_ieee_float_divide(1, tScale) - tBias) * 360);
39 }
40
41 sk_sp<SkFlattenable> SkSweepGradient::CreateProc(SkReadBuffer& buffer) {
42     DescriptorScope desc;
43     if (!desc.unflatten(buffer)) {
44         return nullptr;
45     }
46     const SkPoint center = buffer.readPoint();
47
48     const auto tBias  = buffer.readScalar(),
49                tScale = buffer.readScalar();
50     auto [startAngle, endAngle] = angles_from_t_coeff(tBias, tScale);
51
52     return SkGradientShader::MakeSweep(center.x(), center.y(), desc.fColors,
53                                        std::move(desc.fColorSpace), desc.fPos, desc.fCount,
54                                        desc.fTileMode, startAngle, endAngle,
55                                        desc.fGradFlags, desc.fLocalMatrix);
56 }
57
58 void SkSweepGradient::flatten(SkWriteBuffer& buffer) const {
59     this->INHERITED::flatten(buffer);
60     buffer.writePoint(fCenter);
61     buffer.writeScalar(fTBias);
62     buffer.writeScalar(fTScale);
63 }
64
65 void SkSweepGradient::appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* p,
66                                            SkRasterPipeline*) const {
67     p->append(SkRasterPipeline::xy_to_unit_angle);
68     p->append_matrix(alloc, SkMatrix::Scale(fTScale, 1) * SkMatrix::Translate(fTBias, 0));
69 }
70
71 skvm::F32 SkSweepGradient::transformT(skvm::Builder* p, skvm::Uniforms* uniforms,
72                                       skvm::Coord coord, skvm::I32* mask) const {
73     skvm::F32 xabs = abs(coord.x),
74               yabs = abs(coord.y),
75              slope = min(xabs, yabs) / max(xabs, yabs);
76     skvm::F32 s = slope * slope;
77
78     // Use a 7th degree polynomial to approximate atan.
79     // This was generated using sollya.gforge.inria.fr.
80     // A float optimized polynomial was generated using the following command.
81     // P1 = fpminimax((1/(2*Pi))*atan(x),[|1,3,5,7|],[|24...|],[2^(-40),1],relative);
82     skvm::F32 phi = slope * poly(s, -7.0547382347285747528076171875e-3f,
83                                     +2.476101927459239959716796875e-2f,
84                                     -5.185396969318389892578125e-2f,
85                                     +0.15912117063999176025390625f);
86     phi = select(   xabs < yabs, (1/4.0f) - phi, phi);
87     phi = select(coord.x < 0.0f, (1/2.0f) - phi, phi);
88     phi = select(coord.y < 0.0f, (1/1.0f) - phi, phi);
89
90     skvm::F32 t = select(is_NaN(phi), p->splat(0.0f)
91                                     , phi);
92
93     if (fTScale != 1.0f || fTBias != 0.0f) {
94         t = t * p->uniformF(uniforms->pushF(fTScale))
95               + p->uniformF(uniforms->pushF(fTScale*fTBias));
96     }
97     return t;
98 }
99
100 /////////////////////////////////////////////////////////////////////
101
102 #if SK_SUPPORT_GPU
103
104 #include "src/gpu/ganesh/gradients/GrGradientShader.h"
105
106 std::unique_ptr<GrFragmentProcessor> SkSweepGradient::asFragmentProcessor(
107         const GrFPArgs& args) const {
108     return GrGradientShader::MakeSweep(*this, args);
109 }
110
111 #endif
112
113 #ifdef SK_ENABLE_SKSL
114 void SkSweepGradient::addToKey(const SkKeyContext& keyContext,
115                                SkPaintParamsKeyBuilder* builder,
116                                SkPipelineDataGatherer* gatherer) const {
117     GradientShaderBlocks::GradientData data(kSweep_GradientType,
118                                             SkM44(this->getLocalMatrix()),
119                                             fCenter, { 0.0f, 0.0f },
120                                             0.0, 0.0f,
121                                             fTBias, fTScale,
122                                             fTileMode,
123                                             fColorCount,
124                                             fOrigColors4f,
125                                             fOrigPos);
126
127     GradientShaderBlocks::AddToKey(keyContext, builder, gatherer, data);
128 }
129 #endif