Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkPerlinNoiseShaderImpl.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2013 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
9
23
24#include <optional>
25
27 SkScalar baseFrequencyX,
28 SkScalar baseFrequencyY,
29 int numOctaves,
30 SkScalar seed,
31 const SkISize* tileSize)
32 : fType(type)
33 , fBaseFrequencyX(baseFrequencyX)
34 , fBaseFrequencyY(baseFrequencyY)
35 , fNumOctaves(numOctaves > kMaxOctaves ? kMaxOctaves
36 : numOctaves) // [0,255] octaves allowed
37 , fSeed(seed)
38 , fTileSize(nullptr == tileSize ? SkISize::Make(0, 0) : *tileSize)
39 , fStitchTiles(!fTileSize.isEmpty()) {
41 SkASSERT(fBaseFrequencyX >= 0);
42 SkASSERT(fBaseFrequencyY >= 0);
43
44 // If kBlockSize changes then it must be changed in the SkSL noise_function
45 // implementation and the graphite backend
46 static_assert(SkPerlinNoiseShader::kBlockSize == 256);
47}
48
49sk_sp<SkFlattenable> SkPerlinNoiseShader::CreateProc(SkReadBuffer& buffer) {
51
52 SkScalar freqX = buffer.readScalar();
53 SkScalar freqY = buffer.readScalar();
54 int octaves = buffer.read32LE<int>(kMaxOctaves);
55
56 SkScalar seed = buffer.readScalar();
58 tileSize.fWidth = buffer.readInt();
59 tileSize.fHeight = buffer.readInt();
60
61 switch (type) {
63 return SkShaders::MakeFractalNoise(freqX, freqY, octaves, seed, &tileSize);
65 return SkShaders::MakeTurbulence(freqX, freqY, octaves, seed, &tileSize);
66 default:
67 // Really shouldn't get here b.c. of earlier check on type
68 buffer.validate(false);
69 return nullptr;
70 }
71}
72
74 buffer.writeInt((int)fType);
75 buffer.writeScalar(fBaseFrequencyX);
76 buffer.writeScalar(fBaseFrequencyY);
77 buffer.writeInt(fNumOctaves);
78 buffer.writeScalar(fSeed);
79 buffer.writeInt(fTileSize.fWidth);
80 buffer.writeInt(fTileSize.fHeight);
81}
82
84 const SkShaders::MatrixRec& mRec) const {
85 std::optional<SkShaders::MatrixRec> newMRec = mRec.apply(rec);
86 if (!newMRec.has_value()) {
87 return false;
88 }
89
90 fInitPaintingDataOnce([&] {
91 const_cast<SkPerlinNoiseShader*>(this)->fPaintingData = this->getPaintingData();
92 });
93
95 ctx->noiseType = fType;
96 ctx->baseFrequencyX = fPaintingData->fBaseFrequency.fX;
97 ctx->baseFrequencyY = fPaintingData->fBaseFrequency.fY;
98 ctx->stitchDataInX = fPaintingData->fStitchDataInit.fWidth;
99 ctx->stitchDataInY = fPaintingData->fStitchDataInit.fHeight;
100 ctx->stitching = fStitchTiles;
101 ctx->numOctaves = fNumOctaves;
102 ctx->latticeSelector = fPaintingData->fLatticeSelector;
103 ctx->noiseData = &fPaintingData->fNoise[0][0][0];
104
105 rec.fPipeline->append(SkRasterPipelineOp::perlin_noise, ctx);
106 return true;
107}
108
109///////////////////////////////////////////////////////////////////////////////////////////////////
110
111static bool valid_input(
112 SkScalar baseX, SkScalar baseY, int numOctaves, const SkISize* tileSize, SkScalar seed) {
113 if (!(baseX >= 0 && baseY >= 0)) {
114 return false;
115 }
116 if (!(numOctaves >= 0 && numOctaves <= SkPerlinNoiseShader::kMaxOctaves)) {
117 return false;
118 }
119 if (tileSize && !(tileSize->width() >= 0 && tileSize->height() >= 0)) {
120 return false;
121 }
122 if (!SkIsFinite(seed)) {
123 return false;
124 }
125 return true;
126}
127
130 // Previous name
131 SkFlattenable::Register("SkPerlinNoiseShaderImpl", SkPerlinNoiseShader::CreateProc);
132}
133
134namespace SkShaders {
136 SkScalar baseFrequencyY,
137 int numOctaves,
138 SkScalar seed,
139 const SkISize* tileSize) {
140 if (!valid_input(baseFrequencyX, baseFrequencyY, numOctaves, tileSize, seed)) {
141 return nullptr;
142 }
143
144 if (0 == numOctaves) {
145 // For kFractalNoise, w/o any octaves, the entire shader collapses to:
146 // [0,0,0,0] * 0.5 + 0.5
147 constexpr SkColor4f kTransparentGray = {0.5f, 0.5f, 0.5f, 0.5f};
148
149 return SkShaders::Color(kTransparentGray, /* colorSpace= */ nullptr);
150 }
151
153 baseFrequencyX,
154 baseFrequencyY,
155 numOctaves,
156 seed,
157 tileSize));
158}
159
161 SkScalar baseFrequencyY,
162 int numOctaves,
163 SkScalar seed,
164 const SkISize* tileSize) {
165 if (!valid_input(baseFrequencyX, baseFrequencyY, numOctaves, tileSize, seed)) {
166 return nullptr;
167 }
168
169 if (0 == numOctaves) {
170 // For kTurbulence, w/o any octaves, the entire shader collapses to: [0,0,0,0]
171 return SkShaders::Color(SkColors::kTransparent, /* colorSpace= */ nullptr);
172 }
173
175 baseFrequencyX,
176 baseFrequencyY,
177 numOctaves,
178 seed,
179 tileSize));
180}
181
182} // namespace SkShaders
#define SkASSERT(cond)
Definition SkAssert.h:116
#define SK_REGISTER_FLATTENABLE(type)
static bool SkIsFinite(T x, Pack... values)
static std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap *src, const SkYUVAPixmaps *srcYUVA, const SkColorSpace *srcYUVAColorSpace, const SkJpegEncoder::Options &options)
static bool valid_input(SkScalar baseX, SkScalar baseY, int numOctaves, const SkISize *tileSize, SkScalar seed)
void SkRegisterPerlinNoiseShaderFlattenable()
SkPerlinNoiseShaderType
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))
static void Register(const char name[], Factory)
ShaderType type() const override
SkPerlinNoiseShader(SkPerlinNoiseShaderType type, SkScalar baseFrequencyX, SkScalar baseFrequencyY, int numOctaves, SkScalar seed, const SkISize *tileSize)
bool appendStages(const SkStageRec &rec, const SkShaders::MatrixRec &mRec) const override
std::unique_ptr< PaintingData > getPaintingData() const
void flatten(SkWriteBuffer &) const override
void append(SkRasterPipelineOp, void *=nullptr)
std::optional< MatrixRec > apply(const SkStageRec &rec, const SkMatrix &postInv={}) const
float SkScalar
Definition extension.cpp:12
static const uint8_t buffer[]
constexpr SkColor4f kTransparent
Definition SkColor.h:434
SK_API sk_sp< SkShader > MakeTurbulence(SkScalar baseFrequencyX, SkScalar baseFrequencyY, int numOctaves, SkScalar seed, const SkISize *tileSize=nullptr)
SK_API sk_sp< SkShader > MakeFractalNoise(SkScalar baseFrequencyX, SkScalar baseFrequencyY, int numOctaves, SkScalar seed, const SkISize *tileSize=nullptr)
int32_t fHeight
Definition SkSize.h:18
int32_t fWidth
Definition SkSize.h:17
constexpr int32_t width() const
Definition SkSize.h:36
constexpr int32_t height() const
Definition SkSize.h:37
SkRasterPipeline * fPipeline
SkArenaAlloc * fAlloc